diff --git a/CHANGES b/CHANGES index 3b654aa..b64fb4c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,191 @@ +####################### V 1.8.0.3: + +Security: + readline.sh has new option -lf <logfile> for stderr. If this option is + not given it logs to a file in . (cwd) only when . is not writable by + other users. + +Corrections: + Fixed display of option phases in help output. + + filan -s displayed "(stream)" instead of "tcp" with addresses + (regression). + + Fixed a bug that made ignoreeof fail in 1.8.0.0 and 1.8.0.1; + corrected test IGNOREEOF. + Thanks to Rusty Bird for the precise problem report. + + Fixed the regression introduced with version 1.8.0.1 that in socks5 + addresses the explicit socksport (2nd address parameter) was ignored. + Thanks to Jakub Fišer for reporting this bug. + + Do not log simple successful write with NOTICE level. + + On partial write to not poll with sleep() but use select()/poll(). + + Partial write situations respect total inactivity timeout when + nonblocking. + + Fixed a bug that could lead to error "xiopoll(...): Bad file descriptor" + or to undefined behaviour before terminating Socat with addresses EXEC, + SYSTEM, or SHELL. + + Option ip-add-source-membership did not work. + Thanks to Duncan Sands and others for reporting this issue and sending + the fix. + + Option ip-add-membership with only two parameters crashed or failed + when malloc() does not initialize memory with zeros. + Thanks to Nicolas Cavallari for reporting and fixing this bug. + + The readline() library function does not output the newline of empty + input lines. Changed Socat to explicitly print the newline in this + case. + + Fixed implementation of options o-creat, o-excl, and o-cloexec with + POSIXMQ-* addresses. + POSIXMQ addresses are no longer experimental. + + With version 1.8.0.0, and with 1.8.0.1 and option -0, the following + command failed: + socat UDP-LISTEN:1234,fork,reuseaddr,bind=127.0.0.1 - + Message: "E xioopen_ipdgram_listen(): unknown address family 0": + Thanks to Brian Woo for reporting this issue. + Test: UDP_LISTEN_BIND4 + + Protected SSL_connect() from SIGCHLD,SIGUSR1. + + Nanosleep() trace output now in decimal form. + + UNIX-LISTEN with bind option terminated with INTERNAL error, this is + now handled properly. + Test: UNIX_L_BIND + + Removed unused bytes variable from gettimestamp(), corrected #elsif, + and socks4 record length. + Thanks to clang-18 and gcc-13. + + Address TCP-CONNECT, when target address resolves to both IPv4 and + IPv6, now tries to take into account bind address for protocol + selection. + + Reworked and harmonized ipapp client addresses. + Tests: TCP_CONNECT_RETRY SCTP_CONNECT_RETRY DCCP_CONNECT_RETRY + OPENSSL_CONNECT_RETRY SOCKS4_RETRY SOCKS5_CONNECT_RETRY + PROXY_CONNECT_RETRY + + Socks and proxy clients now also support option max-children. + Tests: TCP_CONNECT_MAXCHILDREN SCTP_CONNECT_MAXCHILDREN + DCCP_CONNECT_MAXCHILDREN OPENSSL_CONNECT_MAXCHILDREN + SOCKS4_MAXCHILDREN SOCKS5_CONNECT_MAXCHILDREN PROXY_CONNECT_MAXCHILDREN + + On failure of getpwuid() (used in options su and su-d) now consider + errno. + + When IP4 was completed deconfigured, UDP6-RECVFROM with range option + failed. + + Fixed preprocessor directives in macro invocation. + Thanks to Mario de Weerd for reporting this issue. + + CONNECT addresses could use a wrong IPPROTO when getaddrinfo() does not + support the selected one (at least on Debian-4 with SCTP). + + socat -h (help) did not show option groups POSIXMQ, SCTP, DCCP, and + UDPLITE of addresses. + +Features: + POSIXMQ-RECV now takes option o-nonblock; this, in combination with -T, + makes it possible to terminate Socat in case the queue is empty. + + New option posixmq-flush (mq-flush) for POSIXMQ addresses empties the + queue before starting to transfer data. + Test: LINUX_POSIXMQ_FLUSH + + New options posixmq-maxmsg, posixmq-msgsize. + Tests: POSIXMQ_MAXMSG POSIXMQ_MSGSIZE + + POSIXMQ is now an alias for POSIXMQ-BIDIRECTIONAL. It can also be used + in unidirectional context. + + Procan uses getresuid() and getresgid() when available, to determine + the saved set-user-ID. + + Procan prints more C-defines, esp.O_*, AI_*, EAI_*; __GLIBC__; + prints some C-defines in oct and hex; + added option -V + + Procan tells if char is signed or unsigned + + Socat now prints an info message when implicitly setting SO_REUSEADDR. + Thanks to Michael Renner for this suggestion. + + Added generic options setsockopt-socket and setsockopt-connected that + are applied after socket() or when connected. + + POSIXMQ addresses now print a warning when options posixmq-maxmsg or + posixmq-msgsize were not applied. + + New address POSIXMQ-WRITE does the same as POSIXMQ-SEND, as counterpart + of POSIXMQ-READ. + +Building: + Disabling certain features during configure could break build process. + + Again fixes a few disable problems. + +Porting: + Fix for old FreeBSD. + + Fixes for old Debian + + Fixes for old Scientific/RHEL + + Socat failed to build on platforms without flock() function (AIX, + Solaris) due to a missing guard. + + Newer Linux distributions do not provide libwrap: do not leave unused + variable. + + Newer Linux distributions deprecate usleep, replace it. + + OpenSSL-3 loudly deprecates some functions or macros, replace a first + bunch of them. + + Fixes for FreeBSD-15 (DCCP) + + Fix for compiling on Solaris-11 + +Testing: + test.sh produces file results.txt with columns of test numbers, names, + and results. + + Fixed a few testing issues. + + Added test script sock5server-echo.sh for SOCKS5-CONNECT and + SOCKS5-LISTEN, and appropriate tests. + SOCKS5 addresses are no longer experimental. + Tests: SOCKS5CONNECT_TCP4 SOCKS5LISTEN_TCP4 + + Added a developer test that overwrites malloc'ed memory with non-zeros. + + Newer Linux distributions now deprecate usleep; replaced it in test.sh + + UDPLITE4STREAM was trice, changed one of them to UDPLITE6STREAM. + + Catch problems caused by ISPs that filter *.dest-unreach.net records. + +Documentation: + Removed obsolete CHANGES.ISO-8859-1 file. + + Corrected lots of misspelling and typos. + Thanks to Mario de Weerd for reporting these issues. + + Improved README file. + + Better explained benefit of UDP-DATAGRAM address type. + ####################### V 1.8.0.2: Security: @@ -70,6 +257,9 @@ Corrections: Print warning about not checking CRLs in OpenSSL only in the first child process. + Fixed preprocessor directives in macro invocation. + Thanks to Mario de Weerd for reporting this issue. + Features: Total inactivity timeout option -T 0 now means 0.0 seconds; up to version 1.8.0.0 it meant no total inactivity timeout. @@ -237,11 +427,11 @@ Features: no IP version is preferred by build, environment, option, or address type, Socat chooses IPv6 because this might activate both versions (but check option ipv6-v6only). - Added option ai-passive to control this flag explicitely. + Added option ai-passive to control this flag explicitly. New option ai-v4mapped (v4mapped) sets or unsets the AI_V4MAPPED flag of the resolver. For Socat addresses requiring IPv6 addresses, this - resolves IPv4 addresses to the approriate IPv6 address [::ffff:*:*]. + resolves IPv4 addresses to the appropriate IPv6 address [::ffff:*:*]. DNS resolver Options (res-*) are now set for the complete open phase of the address, not per getaddrinfo() invocation. @@ -434,14 +624,14 @@ Porting: Some corrections for better 32bit systems support. Testing: - Removed obselete parts from test.sh + Removed obsolete parts from test.sh test.sh: Introduced function checkcond Renamed test.sh option -foreign to -internet Documentation: - Removed obselete file doc/xio.help + Removed obsolete file doc/xio.help Added doc for option ipv6-join-group (ipv6-add-membership) Thanks to Martin Buck for sending the patch. @@ -454,7 +644,7 @@ Documentation: Corrections: On connect() failure and in some other situations Socat tries to get - detailled information about the error with recvmsg(). Error return of + detailed information about the error with recvmsg(). Error return of this function is now logged as Info instead of Warn. Tests of the correction of the "IP_ADD_SOURCE_MEMBERSHIP but not struct @@ -498,7 +688,7 @@ Corrections: Thanks to Gordon W.Ross for reporting and fixing this issue. Test: RESTORE_TTY - The OpenSSL client SNI parameter, when not explicitely specified, is + The OpenSSL client SNI parameter, when not explicitly specified, is derived from option commonname or rom target server name. This is not useful with IP addresses, which Socat now checks and avoids. @@ -529,7 +719,7 @@ Coding: fcntl() trace prints flags now in hexadecimal. - Stream dump options -r and -R now open their pathes with CLOEXEC to + Stream dump options -r and -R now open their paths with CLOEXEC to prevent leaking into sub processes. Test: EXEC_SNIFF @@ -828,7 +1018,7 @@ Corrections: Print a message when readbytes option causes EOF The ip-recverr option had no effect. Corrected and improved its - handling of ancilliary messages, so it is able to analyze ICMP error + handling of ancillary messages, so it is able to analyze ICMP error packets (Linux only?) Setgui(), Setuid() calls in xio-progcall.c were useless. @@ -862,11 +1052,11 @@ Corrections: Under certain conditions OpenSSL stream connections, in particular bulk data transfer in unidirectional mode, failed during transfer or near - its with Connection reset by peer on receiver side. + its end with Connection reset by peer on receiver side. This happened with Socat versions 1.7.3.3 to 1.7.4.0. Reasons were lazy SSL shutdown handling on the sender side in combination with SSL_MODE_AUTO_RETRY turned off. - Fix: After SSH_shutdown but before socket shutdown call SSL_read() + Fix: After SSL_shutdown() but before socket shutdown call SSL_read() Test: OPENSSL_STREAM_TO_SERVER Fixes Red Hat issue 1870279. @@ -966,7 +1156,7 @@ Porting: ai_protocol=0 and try again Test: SCTP_SERVICENAME - Per file filesystem options were still named ext2-* and depended on + Per file filesystem options were still named ext2-* and dependent on <linux/ext2_fs.h>. Now they are called fs-* and depend on <linux/fs.h>. These fs-* options are also available on old systems with ext2_fs.h @@ -979,14 +1169,14 @@ Porting: SSL_library_init. With OPENSSL_API_COMPAT=0x10000000L the files openssl/dh.h, openssl/bn.h - must explicitely be included. + must explicitly be included. Thanks to Rosen Penev for reporting and sending a patch. Testing: test.sh now produces a list of tests that could not be performed for any reason. This helps to analyse these cases. - OpenSSL s_server appearently started to neglect TCPs half close feature. + OpenSSL s_server apparently started to neglect TCPs half close feature. Test OPENSSL_TCP4 has been changed to tolerate this. OpenSSL changed its behaviour when connection is rejected. Tests @@ -1180,7 +1370,7 @@ Corrections: Porting: OpenSSL functions TLS1_client_method() and similar are deprecated. Socat now uses recommended TLS_client_method(). The old - functions and dependend option openssl-method can still be + functions and dependent option openssl-method can still be used when configuring socat with --enable-openssl-method Shell scripts in socat distribution are now headed with: @@ -1222,7 +1412,7 @@ Testing: More corrections to test.sh: Language settings could still influence test results netstat was still required - Suppress usleep deprecated messag + Suppress usleep deprecated message Force use of IPv4 with some certificates Set timeout for UDPxMAXCHILDREN tests @@ -1375,7 +1565,7 @@ testing: docu: Corrected source of socat man page to correctly show man references - like socket(2); removed obseolete entries from See Also + like socket(2); removed obsolete entries from See Also Docu and some comments mentioned addresses SSL-LISTEN and SSL-CONNECT that do not exist (OPENSSL-LISTEN, SSL-L; and OPENNSSL-CONNECT, SSL @@ -1410,6 +1600,7 @@ security: Socat security advisory 7 MSVR-1499 + CVE-2016-2217 In the OpenSSL address implementation the hard coded 1024 bit DH p parameter was not prime. The effective cryptographic strength of a key exchange using these parameters was weaker than the one one could get by @@ -1417,7 +1608,7 @@ security: parameters were chosen, the existence of a trapdoor that makes possible for an eavesdropper to recover the shared secret from a key exchange that uses them cannot be ruled out. - Futhermore, 1024bit is not considered sufficiently secure. + Furthermore, 1024bit is not considered sufficiently secure. Fix: generated a new 2048bit prime. Thanks to Santiago Zanella-Beguelin and Microsoft Vulnerability Research (MSVR) for finding and reporting this issue. @@ -1431,7 +1622,7 @@ security: safe functions in signal handlers that could freeze socat, allowing denial of service attacks. Many changes in signal handling and the diagnostic messages system were - applied to make the code async signal safe but still provide detailled + applied to make the code async signal safe but still provide detailed logging from signal handlers: Coded function vsnprintf_r() as async signal safe incomplete substitute of libc vsnprintf() @@ -1519,7 +1710,7 @@ corrections: Issue reported by Hendrik. Added option termios-cfmakeraw that calls cfmakeraw() and is preferred - over option raw which is now obsolote. On SysV systems this call is + over option raw which is now obsolete. On SysV systems this call is simulated by appropriate setting. Thanks to Youfu Zhang for reporting issue with option raw. @@ -1532,7 +1723,7 @@ porting: Thanks to Ross Burton and Danomi Manchego for reporting this issue. Debian Bug#764251: Set the build timestamp to a deterministic time: - support external BUILD_DATE env var to allow to build reproducable + support external BUILD_DATE env var to allow to build reproducible binaries Joachim Fenkes provided an new adapted spec file. @@ -1653,7 +1844,7 @@ porting: autoconf now prefers configure.ac over configure.in Thanks to Michael Vastola for sending a patch. - type of struct cmsghdr.cmsg is system dependend, determine it with + type of struct cmsghdr.cmsg is system dependent, determine it with configure; some more print format corrections docu: @@ -1707,7 +1898,7 @@ corrections: socket using address GOPEN. Thanks to Martin Forssen for bug report and patch. - UDP-LISTEN would alway set SO_REUSEADDR even without fork option and + UDP-LISTEN would always set SO_REUSEADDR even without fork option and when user set it to 0. Thanks to Michal Svoboda for reporting this bug. UNIX-CONNECT did not support half-close. Thanks to Greg Hughes who @@ -1940,7 +2131,7 @@ new features: added generic socket addresses: SOCKET-CONNECT, SOCKET-LISTEN, SOCKET-SENDTO, SOCKET-RECVFROM, SOCKET-RECV, SOCKET-DATAGRAM allow - protocol independent socket handling; all parameters are explicitely + protocol independent socket handling; all parameters are explicitly specified as numbers or hex data added address options ioctl-void, ioctl-int, ioctl-intp, ioctl-string, @@ -2013,7 +2204,7 @@ corrections: this bug). test: EXECSPACES in ignoreeof polling mode socat also blocked data transfer in the other - direction during the 1s wait intervalls (thanks to Jorgen Cederlof for + direction during the 1s wait intervals (thanks to Jorgen Cederlof for reporting this bug) corrected alphabetical order of options (proxy-auth) @@ -2439,7 +2630,7 @@ corrections: check for /proc at runtime, even if configure found it - src.rpm accidently supported SuSE instead of RedHat + src.rpm accidentally supported SuSE instead of RedHat ####################### V 1.3.2.0: @@ -2715,7 +2906,7 @@ solved problems and bugs: SOLVED: now uses common TCP service resolver PROBLEM: with PIPE, wrong FDs were shown for data transfer loop - SOLVED: retrieval of FDs now pays respect to PIPE pecularities + SOLVED: retrieval of FDs now pays respect to PIPE peculiarities PROBLEM: using address EXEC against an address with IGNOREEOF, socat never terminated diff --git a/CHANGES.ISO-8859-1 b/CHANGES.ISO-8859-1 deleted file mode 100644 index 9509e36..0000000 --- a/CHANGES.ISO-8859-1 +++ /dev/null @@ -1,1800 +0,0 @@ - -####################### V 1.7.3.4: - -Corrections: - Header of xiotermios_speed() declared parameter unsigned int instead of - speed_t, thus compiling failed on MacOS - Thanks to Joe Strout and others for reporting this bug. - Thanks to Andrew Childs and others for sending a patch. - - Under certain circumstances, termios options of the first address were - applied to the second address, resulting in error - "Inappropriate ioctl for device" - This affected version 1.7.3.3 only. - Test: TERMIOS_PH_ALL - Thanks to Ivan J. for reporting this issue. - - Socat failed to compile when no poll() system call was found by - configure. - Thanks to Jason White for sending a patch. - - Due to use of SSL_CTX_clear_mode() Socat failed to compile on old - systems with, e.g., OpenSSL-0.9.8. Thanks to Simon Matter and Moritz B. - for reporting this problem and sending initial patches. - - getaddrinfo() in IP4-SENDTO and IP6-SENDTO addresses failed with - "ai_socktype not supported" when protocol 6 was addressed. - The fix removes the possibility to use service names with SCTP. - Test: IP_SENDTO_6 - Thanks to S�ren for sending an initial patch. - - Under certain circumstances, Socat printed the "socket ... is at EOF" - multiple times. - Test: MULTIPLE_EOF - - Newer parts of test.sh used substitutions ${x,,*} or ${x^^*} that are - not implemented in older bash versions. - -####################### V 1.7.3.3: - -Corrections: - Makefile.in did not specify dependencies of filan on vsnprintf_r.o - and snprinterr.o - Added definition of FILAN_OBJS - Thanks to Craig Leres, Clayton Shotwell, and Chris Packham for - providing patches. - - configure option --enable-msglevel did not work with numbers - - The autoconf mechanism for determining SHIFT_OFFSET did not work when - cross compiling. - Thanks to Max Freisinger from Gentoo for sending a patch. - - Socat still depended on obsolete gethostbyname() function, thus - compiling with MUSL libc failed. - Problem reported by Kennedy33. - - The async signal safe diagnostic system used FDs 3 and 4 internally, so - use of appropriate fdin or fdout led to failures. - Test: DIAG_FDIN - Problem reported by Onur Sent�rk. - - The socket based mechanism for passing messages and signal information - from signal handler to process could reach and kill the wrong process. - Introduces functions diag_sock_pair(), diag_fork() - Thanks to Darren Zhao for analysing and reporting this problem. - - Option ipv6-join-group did not work because it was applied in the wrong - phase - Test: UDP6MULTICAST_UNIDIR - Thanks to Angus Gratton for sending a patch. - - Setting ispeed and ospeed failed for some serial devices because the - two settings were applied with two different get/set cycles, Thanks to - Alexandre Fenyo for providing an initial patch. - However, the actual fix is part of a conceptual change of the termios - module that aims for applying all changes in a single tcsetaddr call. - Fixes FreeBSD Bug 198441 - - Termios options TAB0,TAB1,TAB2,TAB3, and XTABS did not have an effect. - Thanks to Alan Walters for reporting this bug. - - Substituted cumbersom ISPEED_OFFSET mechanism for cfsetispeed() calls - - With TCP6-LISTEN and the other passive IPv6 addresses the range option - just failed: due to a bug in the syntax parser and two more bugs in - the xiocheckrange_ip6() function. - The syntax has now been changed from "[::1/128]" to "[::1]/128"! - Thanks Leah Neukirchen for sending an initial fix. - - For name resolution Socat only checked the first character of the host - name to decide if it is an IPv4 address. This was not RFC conform. This - fix removes the possibility for use of IPv4 addresses with IPv6, e.g. - TCP6:127.0.0.1:80 - Debian issue 695885 - Thanks to Nicolas Fournil for reporting this issue. - - Print a useful error message when single character options appear to be - merged in Socat invocation - Test: SOCCAT_OPT_HINT - - Fixed some docu typos. - Thanks to Travis Wellman, Thomas <tjps636>, Dan Kenigsberg, - Julian Zinn, and Simon Matter - -Porting: - OpenSSL functions TLS1_client_method() and similar are - deprecated. Socat now uses recommended TLS_client_method(). The old - functions and dependend option openssl-method can still be - used when configuring socat with --enable-openssl-method - - Shell scripts in socat distribution are now headed with: - #! /usr/bin/env bash - to make them better portable to systems without /bin/bash - Thanks to Maya Rashish for sending a patch - - RES_AAONLY, RES_PRIMARY are deprecated. You can still enable them with - configure option --enable-res-deprecated. - - New versions of OpenSSL preset SSL_MODE_AUTO_RETRY which may hang socat. - Solution: clear SSL_MODE_AUTO_RETRY when it is set. - - Renamed configure.in to configure.ac and set an appropriate symlink for - older environments. - Related Gentoo bug 426262: Warning on configure.in - Thanks to Francesco Turco for reporting that warning. - - Fixed new IPv6 range code for platforms without s6_addr32 component. - -Testing: - test.sh: Show a warning when phase-1 (insecure phase) of a security - test fails - - OpenSSL tests failed on actual Linux distributions. Measures: - Increased key lengths from 768 to 1024 bits - Added test.sh option -C to delete temp certs from prevsious runs - Provide DH-parameter in certificate in PEM - OpenSSL s_server option -verify 0 must be omitted - OpenSSL authentication method aNULL no longer works - Failure of cipher aNULL is not a failure - Failure of methods SSL3 and SSL23 is desired - - test.sh depended on ifconfig and netstat utilities which are no longer - availabie in some distributions. test.sh now checks for and prefers - ip and ss. - Thanks to Ruediger Meier for reporting this problem. - - More corrections to test.sh: - Language settings could still influence test results - netstat was still required - Suppress usleep deprecated messag - Force use of IPv4 with some certificates - Set timeout for UDPxMAXCHILDREN tests - -Git: - Added missing Config/Makefile.DragonFly-2-8-2, - Config/config.DragonFly-2-8-2.h - Removed testcert.conf (to be generated by test.sh) - -Cosmetics: - Simplified handling of missing termios defines. - -New features: - Permit combined -d options as -dd etc. - -####################### V 1.7.3.2: - -corrections: - SIGSEGV and other signals could lead to a 100% CPU loop - - Failing name resolution could lead to SIGSEGV - Thanks to Max for reporting this issue. - - Include <stddef.h> for ptrdiff_t - Thanks to Jeroen Roovers for reporting this issue. - - Building with --disable-sycls failed due to missing sslcls.h defines - - Socat hung when configured with --disable-sycls. - - Some minor corrections with includes etc. - - Option so-reuseport did not work. Thanks to Some Raghavendra Prabhu - for sending a patch. - - Programs invoked with EXEC, nofork, and -u or -U had stdin and stdout - incorrectly assigned - Test: EXEC_NOFORK_UNIDIR - Thanks to David Reiss for reporting this problem. - - Socat exited with status 0 even when a program invoked with SYSTEM or - EXEC failed. - Tests: SYSTEM_RC EXEC_RC - Issue reported by Felix Winkelmann. - - AddressSanitizer reported a few buffer overflows (false positives). - Nevertheless fixed Socat source. - Issue reported by Hanno B�ck. - - Socat did not use option ipv6-join-group. - Test: USE_IPV6_JOIN_GROUP - Thanks to Linus L�ssing for sending a patch. - - UDP-LISTEN did not honor the max-children option. - Test: UDP4MAXCHILDREN UDP6MAXCHILDREN - Thanks to Leander Berwers for reporting this issue. - - Options so-rcvtimeo and so-sndtimeo do not work with poll()/select() - and therefore were useless. - Thanks to Steve Borenstein for reporting this issue. - - Option dhparam was documented as dhparams. Added the alias name - dhparams to fix this. - Thanks to Alexander Neumann for sending a patch. - - Options shut-down and shut-close did not work. - Thanks to Stefan Schimanski for providing a patch. - - There was a bug in printing readline log message caused by a misleading - indentation. - Thanks to Paul Wouters for reporting. - - The internal vsnprintf_r function looped or crashed on size parameter - with hexadecimal output. - - Ignore exit code of child process when it was killed by master due to - EOF - - Corrected byte order on read of IPV6_TCLASS value from ancillary - message - - Fixed type of the bool element in options. This had bug caused failures - e.g. of ignoreeof on big-endian systems when bool was not based on int. - - On systems with predefined bool type whose size differs from int some - IPv6 and TCP options (per setsockopt()) failed. - - Length of integral data in ancillary messages varies (TOS: 1 byte, - TTL: 4 bytes), the old implementation failed for TTL on big-endian - hosts. - - Fixed an issue in options processing: TUN and DNS flags had failed on - big-endian systems and the NO- forms had probable never worked. - -porting: - Type conflict between int and sig_atomic_t between declaration and - definition of diag_immediate_type and diag_immediate_exit broke - compilation on FreeBSD 10.1 with clang. Thanks to Emanuel Haupt for - reporting this bug. - - Socat failed to compile on platforms with OpenSSL without - DTLSv1_client_method or DTLSv1_server_method. - Thanks to Simon Matter for sending a patch. - - NuttX OS headers do not provide struct ip, thus socat did not compile. - Made struct ip subject to configure. - Thanks to SP for reporting this issue. - - Socat failed to compile with OpenSSL version 1.0.2d where - SSLv3_server_method and SSLv3_client_method are no longer defined. - Thanks to Mischa ter Smitten for reporting this issue and providing - a patch. - - configure checked for OpenSSL EC_KEY assuming it is a define but it - is a type, thus OpenSSL ECDHE ciphers failed even on Linux. - Thanks to Andrey Arapov for reporting this bug. - - Changes to make socat compile with OpenSSL 1.1. - Thanks to Sebastian Andrzej Siewior e.a. from the Debian team for - providing the base patch. - Debian Bug#828550 - - Make Socat compatible with BoringSSL. - Thanks to Matt Braithwaite for providing a patch. - - OpenSSL: Use RAND_status to determine PRNG state - Thanks to Adam Langley for providing a patch - - AIX-7 uses an extended O_ACCMODE that does not fit socat's internal - requirements. Thanks to Garrick Trowsdale for providing a patch - - LibreSSL support: check for OPENSSL_NO_COMP - Thanks to Bernard Spil for providing a patch - -testing: - socks4echo.sh and socks4a-echo.sh hung with new bash with read -n - - test.sh: stderr; option -v (verbose); FDOUT_ERROR description - - improved proxy.sh - it now also takes hostnames - - A few corrections in test.sh - - DTLS1 test hangs on some distributions. Test is now only performed - with OpenSSL 1.0.2 or higher. - - More corrections to test.sh that reveal a mistake with IPV6_TCLASS - -docu: - Corrected source of socat man page to correctly show man references - like socket(2); removed obseolete entries from See Also - - Docu and some comments mentioned addresses SSL-LISTEN and SSL-CONNECT - that do not exist (OPENSSL-LISTEN, SSL-L; and OPENNSSL-CONNECT, SSL - are correct). - Thanks to Zhigang Wang for reporting this issue. - - Fixed a couple of English spelling and grammar mistakes. - Thanks to Jakub Wild for sending the patches. - - NOEXPAND() was not resolved 2 times. - - More minor docu corrections - -legal: - Added contributors to copyright notices. Suggested by Matt Braithwaite. - -####################### V 1.7.3.1: - -security: - Socat security advisory 8 - A stack overflow in vulnerability was found that can be triggered when - command line arguments (complete address specifications, host names, - file names) are longer than 512 bytes. - Successful exploitation might allow an attacker to execute arbitrary - code with the privileges of the socat process. - This vulnerability can only be exploited when an attacker is able to - inject data into socat's command line. - A vulnerable scenario would be a CGI script that reads data from clients - and uses (parts of) this data as hostname for a Socat invocation. - Test: NESTEDOVFL - Credits to Takumi Akiyama for finding and reporting this issue. - - Socat security advisory 7 - MSVR-1499 - In the OpenSSL address implementation the hard coded 1024 bit DH p - parameter was not prime. The effective cryptographic strength of a key - exchange using these parameters was weaker than the one one could get by - using a prime p. Moreover, since there is no indication of how these - parameters were chosen, the existence of a trapdoor that makes possible - for an eavesdropper to recover the shared secret from a key exchange - that uses them cannot be ruled out. - Futhermore, 1024bit is not considered sufficiently secure. - Fix: generated a new 2048bit prime. - Thanks to Santiago Zanella-Beguelin and Microsoft Vulnerability - Research (MSVR) for finding and reporting this issue. - -####################### V 1.7.3.0: - -security: - Socat security advisory 6 - CVE-2015-1379: Possible DoS with fork - Fixed problems with signal handling caused by use of not async signal - safe functions in signal handlers that could freeze socat, allowing - denial of service attacks. - Many changes in signal handling and the diagnostic messages system were - applied to make the code async signal safe but still provide detailled - logging from signal handlers: - Coded function vsnprintf_r() as async signal safe incomplete substitute - of libc vsnprintf() - Coded function snprinterr() to replace %m in strings with a system error - message - Instead of gettimeofday() use clock_gettime() when available - Pass Diagnostic messages from signal handler per unix socket to the main - program flow - Use sigaction() instead of signal() for better control - Turn off nested signal handler invocations - Thanks to Peter Lobsinger for reporting and explaining this issue. - - Red Hat issue 1019975: add TLS host name checks - OpenSSL client checks if the server certificates names in - extensions/subjectAltName/DNS or in subject/commonName match the name - used to connect or the value of the openssl-commonname option. - Test: OPENSSL_CN_CLIENT_SECURITY - - OpenSSL server checks if the client certificates names in - extensions/subjectAltNames/DNS or subject/commonName match the value of - the openssl-commonname option when it is used. - Test: OPENSSL_CN_SERVER_SECURITY - - Red Hat issue 1019964: socat now uses the system certificate store with - OPENSSL when neither options cafile nor capath are used - - Red Hat issue 1019972: needs to specify OpenSSL cipher suites - Default cipherlist is now "HIGH:-NULL:-PSK:-aNULL" instead of empty to - prevent downgrade attacks - -new features: - OpenSSL addresses set couple of environment variables from values in - peer certificate, e.g.: - SOCAT_OPENSSL_X509_SUBJECT, SOCAT_OPENSSL_X509_ISSUER, - SOCAT_OPENSSL_X509_COMMONNAME, - SOCAT_OPENSSL_X509V3_SUBJECTALTNAME_DNS - Tests: ENV_OPENSSL_{CLIENT,SERVER}_X509_* - - Added support for methods TLSv1, TLSv1.1, TLSv1.2, and DTLS1 - Tests: OPENSSL_METHOD_* - - Enabled OpenSSL server side use of ECDHE ciphers. Feature suggested - by Andrey Arapov. - - Added a new option termios-rawer for ptys. - Thanks to Christian Vogelgsang for pointing me to this requirement - -corrections: - Bind with ABSTRACT commands used non-abstract namespace (Linux). - Test: ABSTRACT_BIND - Thanks to Denis Shatov for reporting this bug. - - Fixed return value of nestlex() - - Option ignoreeof on the right address hung. - Test: IGNOREEOF_REV - Thanks to Franz Fasching for reporting this bug. - - Address SYSTEM, when terminating, shut down its parent addresses, - e.g. an SSL connection which the parent assumed to still be active. - Test: SYSTEM_SHUTDOWN - - Passive (listening or receiving) addresses with empty port field bound - to a random port instead of terminating with error. - Test: TCP4_NOPORT - - configure with some combination of disable options produced config - files that failed to compile due to missing IPPROTO_TCP. - Thanks to Thierry Fournier for report and patch. - - fixed a few minor bugs with OpenSSL in configure and with messages - - Socat did not work in FIPS mode because 1024 instead of 512 bit DH prime - is required. Thanks to Zhigang Wang for reporting and sending a patch. - - Christophe Leroy provided a patch that fixes memory leaks reported by - valgrind - - Help for filan -L was bad, is now corrected to: - "follow symbolic links instead of showing their properties" - - Address options fdin and fdout were silently ignored when not applicable - due to -u or -U option. Now these combinations are caught as errors. - Test: FDOUT_ERROR - Issue reported by Hendrik. - - Added option termios-cfmakeraw that calls cfmakeraw() and is preferred - over option raw which is now obsolote. On SysV systems this call is - simulated by appropriate setting. - Thanks to Youfu Zhang for reporting issue with option raw. - -porting: - Socat included <sys/poll.h> instead of POSIX <poll.h> - Thanks to John Spencer for reporting this issue. - - Version 1.7.2.4 changed the check for gcc in configure.ac; this - broke cross compiling. The particular check gets reverted. - Thanks to Ross Burton and Danomi Manchego for reporting this issue. - - Debian Bug#764251: Set the build timestamp to a deterministic time: - support external BUILD_DATE env var to allow to build reproducable - binaries - - Joachim Fenkes provided an new adapted spec file. - - Type bool and macros Min and Max are defined by socat which led to - compile errors when they were already provided by build framework. - Thanks to Liyu Liu for providing a patch. - - David Arnstein contributed a patch for NetBSD 5.1 including stdbool.h - support and appropriate files in Config/ - - Lauri Tirkkonen contributed a patch regarding netinet/if_ether.h - on Illumos - - Changes for Openindiana: define _XPG4_2, __EXTENSIONS__, - _POSIX_PTHREAD_SEMANTICS; and minor changes - - Red Hat issue 1182005: socat 1.7.2.4 build failure missing - linux/errqueue.h - Socat failed to compile on on PPC due to new requirements for - including <linux/errqueue.h> and a weakness in the conditional code. - Thanks to Michel Normand for reporting this issue. - -doc: - In the man page the PTY example was badly formatted. Thanks to - J.F.Sebastian for sending a patch. - - Added missing CVE ids to security issues in CHANGES - -testing: - Do not distribute testcert.conf with socat source but generate it - (and new testcert6.conf) during test.sh run. - -####################### V 1.7.2.4: - -corrections: - LISTEN based addresses applied some address options, e.g. so-keepalive, - to the listening file descriptor instead of the connected file - descriptor - Thanks to Ulises Alonso for reporting this bug - - make failed after configure with non gcc compiler due to missing - include. Thanks to Horacio Mijail for reporting this problem - - configure checked for --disable-rawsocket but printed - --disable-genericsocket in the help text. Thanks to Ben Gardiner for - reporting and patching this bug - - In xioshutdown() a wrong branch was chosen after RECVFROM type addresses. - Probably no impact. - Thanks to David Binderman for reporting this issue. - - procan could not cleanly format ulimit values longer than 16 decimal - digits. Thanks to Frank Dana for providing a patch that increases field - width to 24 digits. - - OPENSSL-CONNECT with bind option failed on some systems, eg.FreeBSD, with - "Invalid argument" - Thanks to Emile den Tex for reporting this bug. - - Changed some variable definitions to make gcc -O2 aliasing checker happy - Thanks to Ilya Gordeev for reporting these warnings - - On big endian platforms with type long >32bit the range option applied a - bad base address. Thanks to hejia hejia for reporting and fixing this bug. - - Red Hat issue 1022070: missing length check in xiolog_ancillary_socket() - - Red Hat issue 1022063: out-of-range shifts on net mask bits - - Red Hat issue 1022062: strcpy misuse in xiosetsockaddrenv_ip4() - - Red Hat issue 1022048: strncpy hardening: corrected suspicious strncpy() - uses - - Red Hat issue 1021958: fixed a bug with faulty buffer/data length - calculation in xio-ascii.c:_xiodump() - - Red Hat issue 1021972: fixed a missing NUL termination in return string - of sysutils.c:sockaddr_info() for the AF_UNIX case - - fixed some typos and minor issues, including: - Red Hat issue 1021967: formatting error in manual page - - UNIX-LISTEN with fork option did not remove the socket file system entry - when exiting. Other file system based passive address types had similar - issues or failed to apply options umask, user e.a. - Thanks to Lorenzo Monti for pointing me to this issue - -porting: - Red Hat issue 1020203: configure checks fail with some compilers. - Use case: clang - - Performed changes for Fedora release 19 - - Adapted, improved test.sh script - - Red Hat issue 1021429: getgroupent fails with large number of groups; - use getgrouplist() when available instead of sequence of calls to - getgrent() - - Red Hat issue 1021948: snprintf API change; - Implemented xio_snprintf() function as wrapper that tries to emulate C99 - behaviour on old glibc systems, and adapted all affected calls - appropriately - - Mike Frysinger provided a patch that supports long long for time_t, - socklen_t and a few other libc types. - - Artem Mygaiev extended Cedril Priscals Android build script with pty code - - The check for fips.h required stddef.h - Thanks to Matt Hilt for reporting this issue and sending a patch - - Check for linux/errqueue.h failed on some systems due to lack of - linux/types.h inclusion. Thanks to Michael Vastola for sending a patch. - - autoconf now prefers configure.ac over configure.in - Thanks to Michael Vastola for sending a patch. - - type of struct cmsghdr.cmsg is system dependend, determine it with - configure; some more print format corrections - -docu: - libwrap always logs to syslog - - added actual text version of GPLv2 - -####################### V 1.7.2.3: - -security: - Socat security advisory 5 - CVE-2014-0019: socats PROXY-CONNECT address was vulnerable to a buffer - overflow with data from command line (see socat-secadv5.txt) - Credits to Florian Weimer of the Red Hat Product Security Team - -####################### V 1.7.2.2: - -security: - Socat security advisory 4 - CVE-2013-3571: - after refusing a client connection due to bad source address or source - port socat shutdown() the socket but did not close() it, resulting in - a file descriptor leak in the listening process, visible with lsof and - possibly resulting in EMFILE Too many open files. This issue could be - misused for a denial of service attack. - Full credits to Catalin Mitrofan for finding and reporting this issue. - -####################### V 1.7.2.1: - -security: - Socat security advisory 3 - CVE-2012-0219: - fixed a possible heap buffer overflow in the readline address. This bug - could be exploited when all of the following conditions were met: - 1) one of the addresses is READLINE without the noprompt and without the - prompt options. - 2) the other (almost arbitrary address) reads malicious data (which is - then transferred by socat to READLINE). - Workaround: when using the READLINE address apply option prompt or - noprompt. - Full credits to Johan Thillemann for finding and reporting this issue. - -####################### V 1.7.2.0: - -corrections: - when UNIX-LISTEN was applied to an existing file it failed as expected - but removed the file. Thanks to Bjoern Bosselmann for reporting this - problem - - fixed a bug where socat might crash when connecting to a unix domain - socket using address GOPEN. Thanks to Martin Forssen for bug report and - patch. - - UDP-LISTEN would alway set SO_REUSEADDR even without fork option and - when user set it to 0. Thanks to Michal Svoboda for reporting this bug. - - UNIX-CONNECT did not support half-close. Thanks to Greg Hughes who - pointed me to that bug - - TCP-CONNECT with option nonblock reported successful connect even when - it was still pending - - address option ioctl-intp failed with "unimplemented type 26". Thanks - to Jeremy W. Sherman for reporting and fixing that bug - - socat option -x did not print packet direction, timestamp etc; thanks - to Anthony Sharobaiko for sending a patch - - address PTY does not take any parameters but did not report an error - when some were given - - Marcus Meissner provided a patch that fixes invalid output and possible - process crash when socat prints info about an unnamed unix domain - socket - - Michal Soltys reported the following problem and provided an initial - patch: when socat was interrupted, e.g. by SIGSTOP, and resumed during - data transfer only parts of the data might have been written. - - Option o-nonblock in combination with large transfer block sizes - may result in partial writes and/or EAGAIN errors that were not handled - properly but resulted in data loss or process termination. - - Fixed a bug that could freeze socat when during assembly of a log - message a signal was handled that also printed a log message. socat - development had been aware that localtime() is not thread safe but had - only expected broken messages, not corrupted stack (glibc 2.11.1, - Ubuntu 10.4) - - an internal store for child pids was susceptible to pid reuse which - could lead to sporadic data loss when both fork option and exec address - were used. Thanks to Tetsuya Sodo for reporting this problem and - sending a patch - - OpenSSL server failed with "no shared cipher" when using cipher aNULL. - Fixed by providing temporary DH parameters. Thanks to Philip Rowlands - for drawing my attention to this issue. - - UDP-LISTEN slept 1s after accepting a connection. This is not required. - Thanks to Peter Valdemar Morch for reporting this issue - - fixed a bug that could lead to error or socat crash after a client - connection with option retry had been established - - fixed configure.in bug on net/if.h check that caused IF_NAMESIZE to be - undefined - - improved dev_t print format definition - -porting: - Cedril Priscal ported socat to Android (using Googles cross compiler). - The port includes the socat_buildscript_for_android.sh script - - added check for component ipi_spec_dst in struct in_pktinfo so - compilation does not fail on Cygwin (thanks to Peter Wagemans for - reporting this problem) - - build failed on RHEL6 due to presence of fips.h; configure now checks - for fipsld too. Thanks to Andreas Gruenbacher for reporting this - problem - - check for netinet6/in6.h only when IPv6 is available and enabled - - don't fail to compile when the following defines are missing: - IPV6_PKTINFO IPV6_RTHDR IPV6_DSTOPTS IPV6_HOPOPTS IPV6_HOPLIMIT - Thanks to Jerry Jacobs for reporting this problem (Mac OS X Lion 10.7) - - check if define __APPLE_USE_RFC_2292 helps to enable IPV6_* (MacOSX - Lion 7.1); thanks to Jerry Jacobs to reporting this problem and - proposing a solution - - fixed compiler warnings on Mac OS X 64bit. Thanks to Guy Harris for - providing the patch. - - corrections for OpenEmbedded, especially termios SHIFT values and - ISPEED/OSPEED. Thanks to John Faith for providing the patch - - minor corrections to docu and test.sh resulting from local compilation - on Openmoko SHR - - fixed sa_family_t compile error on DragonFly. Thanks to Tony Young for - reporting this issue and sending a patch. - - Ubuntu Oneiric: OpenSSL no longer provides SSLv2 functions; libutil.sh - is now bsd/libutil.h; compiler warns on vars that is only written to - -new features: - added option max-children that limits the number of concurrent child - processes. Thanks to Sam Liddicott for providing the patch. - - Till Maas added support for tun/tap addresses without IP address - - added an option openssl-compress that allows to disable the compression - feature of newer OpenSSL versions. Thanks to Michael Hanselmann for - providing this contribution (sponsored by Google Inc.) - -docu: - minor corrections in docu (thanks to Paggas) - - client process -> child process - -####################### V 1.7.1.3: - -security: - Socat security advisory 2 - CVE-2010-2799: - fixed a stack overflow vulnerability that occurred when command - line arguments (whole addresses, host names, file names) were longer - than 512 bytes. - Note that this could only be exploited when an attacker was able to - inject data into socat's command line. - Full credits to Felix Gr�bert, Google Security Team, for finding and - reporting this issue - -####################### V 1.7.1.2: - -corrections: - user-late and group-late, when applied to a pty, affected the system - device /dev/ptmx instead of the pty (thanks to Matthew Cloke for - pointing me to this bug) - - socats openssl addresses failed with "nonblocking operation did not - complete" when the peer performed a renegotiation. Thanks to Benjamin - Delpy for reporting this bug. - - info message during socks connect showed bad port number on little - endian systems due to wrong byte order (thanks to Peter M. Galbavy for - bug report and patch) - - Debian bug 531078: socat execs children with SIGCHLD ignored; corrected - to default. Thanks to Martin Dorey for reporting this bug. - -porting: - building socat on systems that predefined the CFLAGS environment to - contain -Wall failed (esp.RedHat). Thanks to Paul Wouters for reporting - this problem and to Simon Matter for providing the patch - - support for Solaris 8 and Sun Studio support (thanks to Sebastian - Kayser for providing the patches) - - on some 64bit systems a compiler warning "cast from pointer to integer - of different size" was issued on some option definitions - - added struct sockaddr_ll to union sockaddr_union to avoid "strict - aliasing" warnings (problem reported by Paul Wouters) - -docu: - minor corrections in docu - -####################### V 1.7.1.1: - -corrections: - corrected the "fixed possible SIGSEGV" fix because SIGSEGV still might - occur under those conditions. Thanks to Toni Mattila for first - reporting this problem. - - ftruncate64 cut its argument to 32 bits on systems with 32 bit long type - - socat crashed on systems without setenv() (esp. SunOS up to Solaris 9); - thanks to Todd Stansell for reporting this bug - - with unidirectional EXEC and SYSTEM a close() operation was performed - on a random number which could result in hanging e.a. - - fixed a compile problem caused by size_t/socklen_t mismatch on 64bit - systems - - docu mentioned option so-bindtodev but correct name is so-bindtodevice. - Thanks to Jim Zimmerman for reporting. - -docu changes: - added environment variables example to doc/socat-multicast.html - -####################### V 1.7.1.0: - -new features: - address options shut-none, shut-down, and shut-close allow to control - socat's half close behaviour - - with address option shut-null socat sends an empty packet to the peer - to indicate EOF - - option null-eof changes the behaviour of sockets that receive an empty - packet to see EOF instead of ignoring it - - introduced option names substuser-early and su-e, currently equivalent - to option substuser (thanks to Mike Perry for providing the patch) - -corrections: - fixed some typos and improved some comments - -####################### V 1.7.0.1: - -corrections: - fixed possible SIGSEGV in listening addresses when a new connection was - reset by peer before the socket addresses could be retrieved. Thanks to - Mike Perry for sending a patch. - - fixed a bug, introduced with version 1.7.0.0, that let client - connections with option connect-timeout fail when the connections - succeeded. Thanks to Bruno De Fraine for reporting this bug. - - option end-close "did not apply" to addresses PTY, SOCKET-CONNECT, - and most UNIX-* and ABSTRACT-* - - half close of EXEC and SYSTEM addresses did not work for pipes and - sometimes socketpair - - help displayed for some option a wrong type - - under some circumstances shutdown was called multiple times for the - same fd - -####################### V 1.7.0.0: - -new features: - new address types SCTP-CONNECT and SCTP-LISTEN implement SCTP stream - mode for IPv4 and IPv6; new address options sctp-maxseg and - sctp-nodelay (suggested by David A. Madore; thanks to Jonathan Brannan - for providing an initial patch) - - new address "INTERFACE" for transparent network interface handling - (suggested by Stuart Nicholson) - - added generic socket addresses: SOCKET-CONNECT, SOCKET-LISTEN, - SOCKET-SENDTO, SOCKET-RECVFROM, SOCKET-RECV, SOCKET-DATAGRAM allow - protocol independent socket handling; all parameters are explicitely - specified as numbers or hex data - - added address options ioctl-void, ioctl-int, ioctl-intp, ioctl-string, - ioctl-bin for generic ioctl() calls. - - added address options setsockopt-int, setsockopt-bin, and - setsockopt-string for generic setsockopt() calls - - option so-type now only affects the socket() and socketpair() calls, - not the name resolution. so-type and so-prototype can now be applied to - all socket based addresses. - - new address option "escape" allows to break a socat instance even when - raw terminal mode prevents ^C etc. (feature suggested by Guido Trotter) - - socat sets environment variables SOCAT_VERSION, SOCAT_PID, SOCAT_PPID - for use in executed scripts - - socat sets environment variables SOCAT_SOCKADDR, SOCAT_SOCKPORT, - SOCAT_PEERADDR, SOCAT_PEERPORT in LISTEN type addresses (feature - suggested by Ed Sawicki) - - socat receives all ancillary messages with each received packet on - datagram related addresses. The messages are logged in raw form with - debug level, and broken down with info level. note: each type of - ancillary message must be enabled by appropriate address options. - - socat provides the contents of ancillary messages received on RECVFROM - addresses in appropriate environment variables: - SOCAT_TIMESTAMP, SOCAT_IP_DSTADDR, SOCAT_IP_IF, SOCAT_IP_LOCADDR, - SOCAT_IP_OPTIONS, SOCAT_IP_TOS, SOCAT_IP_TTL, SOCAT_IPV6_DSTADDR, - SOCAT_IPV6_HOPLIMIT, SOCAT_IPV6_TCLASS - - the following address options were added to enable ancillary messages: - so-timestamp, ip-pktinfo (not BSD), ip-recvdstaddr (BSD), ip-recverr, - ip-recvif (BSD), ip-recvopts, ip-recvtos, ip-recvttl, ipv6-recvdstopts, - ipv6-recverr, ipv6-recvhoplimit, ipv6-recvhopopts, ipv6-recvpathmtu, - ipv6-recvpktinfo, ipv6-recvrthdr, ipv6-recvtclass - - new address options ipv6-tclass and ipv6-unicast-hops set the related - socket options. - - STREAMS (UNIX System V STREAMS) can be configured with the new address - options i-pop-all and i-push (thanks to Michal Rysavy for providing a - patch) - -corrections: - some raw IP and UNIX datagram modes failed on BSD systems - - when UDP-LISTEN continued to listen after packet dropped by, e.g., - range option, the old listen socket would not be closed but a new one - created. open sockets could accumulate. - - there was a bug in ip*-recv with bind option: it did not bind, and - with the first received packet an error occurred: - socket_init(): unknown address family 0 - test: RAWIP4RECVBIND - - RECVFROM addresses with FORK option hung after processing the first - packet. test: UDP4RECVFROM_FORK - - corrected a few mistakes that caused compiler warnings on 64bit hosts - (thanks to Jonathan Brannan e.a. for providing a patch) - - EXEC and SYSTEM with stderr injected socat messages into the data - stream. test: EXECSTDERRLOG - - when the EXEC address got a string with consecutive spaces it created - additional empty arguments (thanks to Olivier Hervieu for reporting - this bug). test: EXECSPACES - - in ignoreeof polling mode socat also blocked data transfer in the other - direction during the 1s wait intervalls (thanks to Jorgen Cederlof for - reporting this bug) - - corrected alphabetical order of options (proxy-auth) - - some minor corrections - - improved test.sh script: more stable timing, corrections for BSD - - replaced the select() calls by poll() to cleanly fix the problems with - many file descriptors already open - - socat option -lf did not log to file but to stderr - - socat did not compile on Solaris when configured without termios - feature (thanks to Pavan Gadi for reporting this bug) - -porting: - socat compiles and runs on AIX with gcc (thanks to Andi Mather for his - help) - - socat compiles and runs on Cygwin (thanks to Jan Just Keijser for his - help) - - socat compiles and runs on HP-UX with gcc (thanks to Michal Rysavy for - his help) - - socat compiles and runs on MacOS X (thanks to Camillo Lugaresi for his - help) - -further changes: - filan -s prefixes output with FD number if more than one FD - - Makefile now supports datarootdir (thanks to Camillo Lugaresi for - providing the patch) - - cleanup in xio-unix.c - -####################### V 1.6.0.1: - -new features: - new make target "gitclean" - - docu source doc/socat.yo released - -corrections: - exec:...,pty did not kill child process under some circumstances; fixed - by correcting typo in xio-progcall.c (thanks to Ralph Forsythe for - reporting this problem) - - service name resolution failed due to byte order mistake - (thanks to James Sainsbury for reporting this problem) - - socat would hang when invoked with many file descriptors already opened - fix: replaced FOPEN_MAX with FD_SETSIZE - thanks to Daniel Lucq for reporting this problem. - - fixed bugs where sub processes would become zombies because the master - process did not catch SIGCHLD. this affected addresses UDP-LISTEN, - UDP-CONNECT, TCP-CONNECT, OPENSSL, PROXY, UNIX-CONNECT, UNIX-CLIENT, - ABSTRACT-CONNECT, ABSTRACT-CLIENT, SOCKSA, SOCKS4A - (thanks to Fernanda G Weiden for reporting this problem) - - fixed a bug where sub processes would become zombies because the master - process caught SIGCHLD but did not wait(). this affected addresses - UDP-RECVFROM, IP-RECVFROM, UNIX-RECVFROM, ABSTRACT-RECVFROM - (thanks to Evan Borgstrom for reporting this problem) - - corrected option handling with STDIO; usecase: cool-write - - configure --disable-pty also disabled option waitlock - - fixed small bugs on systems with struct ip_mreq without struct ip_mreqn - (thanks to Roland Illig for sending a patch) - - corrected name of option intervall to interval (old form still valid - for us German speaking guys) - - corrected some print statements and variable names - - make uninstall did not uninstall procan - - fixed lots of weaknesses in test.sh - - corrected some bugs and typos in doc/socat.yo, EXAMPLES, C comments - -further changes: - procan -c prints C defines important for socat - - added test OPENSSLEOF for OpenSSL half close - -####################### V 1.6.0.0: - -new features: - new addresses IP-DATAGRAM and UDP-DATAGRAM allow versatile broadcast - and multicast modes - - new option ip-add-membership for control of multicast group membership - - new address TUN for generation of Linux TUN/TAP pseudo network - interfaces (suggested by Mat Caughron); associated options tun-device, - tun-name, tun-type; iff-up, iff-promisc, iff-noarp, iff-no-pi etc. - - new addresses ABSTRACT-CONNECT, ABSTRACT-LISTEN, ABSTRACT-SENDTO, - ABSTRACT-RECV, and ABSTRACT-RECVFROM for abstract UNIX domain addresses - on Linux (requested by Zeeshan Ali); option unix-tightsocklen controls - socklen parameter on system calls. - - option end-close for control of connection closing allows FD sharing - by sub processes - - range option supports form address:mask with IPv4 - - changed behaviour of OPENSSL-LISTEN to require and verify client - certificate per default - - options f-setlkw-rd, f-setlkw-wr, f-setlk-rd, f-setlk-wr allow finer - grained locking on regular files - - uninstall target in Makefile (lack reported by Zeeshan Ali) - -corrections: - fixed bug where only first tcpwrap option was applied; fixed bug where - tcpwrap IPv6 check always failed (thanks to Rudolf Cejka for reporting - and fixing this bug) - - filan (and socat -D) could hang when a socket was involved - - corrected PTYs on HP-UX (and maybe others) using STREAMS (inspired by - Roberto Mackun) - - correct bind with udp6-listen (thanks to Jan Horak for reporting this - bug) - - corrected filan.c peekbuff[0] which did not compile with Sun Studio Pro - (thanks to Leo Zhadanovsky for reporting this problem) - - corrected problem with read data buffered in OpenSSL layer (thanks to - Jon Nelson for reporting this bug) - - corrected problem with option readbytes when input stream stayed idle - after so many bytes - - fixed a bug where a datagram receiver with option fork could fork two - sub processes per packet - -further changes: - moved documentation to new doc/ subdir - - new documents (kind of mini tutorials) are provided in doc/ - -####################### V 1.5.0.0: - -new features: - new datagram modes for udp, rawip, unix domain sockets - - socat option -T specifies inactivity timeout - - rewrote lexical analysis to allow nested socat calls - - addresses tcp, udp, tcp-l, udp-l, and rawip now support IPv4 and IPv6 - - socat options -4, -6 and environment variables SOCAT_DEFAULT_LISTEN_IP, - SOCAT_PREFERRED_RESOLVE_IP for control of protocol selection - - addresses ssl, ssl-l, socks, proxy now support IPv4 and IPv6 - - option protocol-family (pf), esp. for openssl-listen - - range option supports IPv6 - syntax: range=[::1/128] - - option ipv6-v6only (ipv6only) - - new tcp-wrappers options allow-table, deny-table, tcpwrap-etc - - FIPS version of OpenSSL can be integrated - initial patch provided by - David Acker. See README.FIPS - - support for resolver options res-debug, aaonly, usevc, primary, igntc, - recurse, defnames, stayopen, dnsrch - - options for file attributes on advanced filesystems (ext2, ext3, - reiser): secrm, unrm, compr, ext2-sync, immutable, ext2-append, nodump, - ext2-noatime, journal-data etc. - - option cool-write controls severeness of write failure (EPIPE, - ECONNRESET) - - option o-noatime - - socat option -lh for hostname in log output - - traffic dumping provides packet headers - - configure.in became part of distribution - - socats unpack directory now has full version, e.g. socat-1.5.0.0/ - - corrected docu of option verify - -corrections: - fixed tcpwrappers integration - initial fix provided by Rudolf Cejka - - exec with pipes,stderr produced error - - setuid-early was ignored with many address types - - some minor corrections - -####################### V 1.4.3.1: - -corrections: - PROBLEM: UNIX socket listen accepted only one (or a few) connections. - FIX: do not remove listening UNIX socket in child process - - PROBLEM: SIGSEGV when TCP part of SSL connect failed - FIX: check ssl pointer before calling SSL_shutdown - - In debug mode, show connect client port even when connect fails - -####################### V 1.4.3.0: - -new features: - socat options -L, -W for application level locking - - options "lockfile", "waitlock" for address level locking - (Stefan Luethje) - - option "readbytes" limits read length (Adam Osuchowski) - - option "retry" for unix-connect, unix-listen, tcp6-listen (Dale Dude) - - pty symlink, unix listen socket, and named pipe are per default removed - after use; option unlink-close overrides this new behaviour and also - controls removal of other socat generated files (Stefan Luethje) - -corrections: - option "retry" did not work with tcp-listen - - EPIPE condition could result in a 100% CPU loop - -further changes: - support systems without SHUT_RD etc. - handle more size_t types - try to find makedepend options with gcc 3 (richard/OpenMacNews) - -####################### V 1.4.2.0: - -new features: - option "connect-timeout" limits wait time for connect operations - (requested by Giulio Orsero) - - option "dhparam" for explicit Diffie-Hellman parameter file - -corrections: - support for OpenSSL DSA certificates (Miika Komu) - - create install directories before copying files (Miika Komu) - - when exiting on signal, return status 128+signum instead of 1 - - on EPIPE and ECONNRESET, only issue a warning (Santiago Garcia - Mantinan) - - -lu could cause a core dump on long messages - -further changes: - modifications to simplify using socats features in applications - -####################### V 1.4.1.0: - -new features: - option "wait-slave" blocks open of pty master side until a client - connects, "pty-intervall" controls polling - - option -h as synonym to -? for help (contributed by Christian - Lademann) - - filan prints formatted time stamps and rdev (disable with -r) - - redirect filan's output, so stdout is not affected (contributed by - Luigi Iotti) - - filan option -L to follow symbolic links - - filan shows termios control characters - -corrections: - proxy address no longer performs unsolicited retries - - filan -f no longer needs read permission to analyze a file (but still - needs access permission to directory, of course) - -porting: - Option dsusp - FreeBSD options noopt, nopush, md5sig - OpenBSD options sack-disable, signature-enable - HP-UX, Solaris options abort-threshold, conn-abort-threshold - HP-UX options b900, b3600, b7200 - Tru64/OSF1 options keepinit, paws, sackena, tsoptena - -further corrections: - address pty now uses ptmx as default if openpty is also available - -####################### V 1.4.0.3: - -security: - Socat security advisory 1 - CVE-2004-1484: - fix to a syslog() based format string vulnerability that can lead to - remote code execution. See advisory socat-adv-1.txt - -####################### V 1.4.0.2: - -corrections: - exec'd write-only addresses get a chance to flush before being killed - - error handler: print notice on error-exit - - filan printed wrong file type information - -####################### V 1.4.0.1: - -corrections: - socks4a constructed invalid header. Problem found, reported, and fixed - by Thomas Themel, by Peter Palfrader, and by rik - - with nofork, don't forget to apply some process related options - (chroot, setsid, setpgid, ...) - -####################### V 1.4.0.0: - -new features: - simple openssl server (ssl-l), experimental openssl trust - - new options "cafile", "capath", "key", "cert", "egd", and "pseudo" for - openssl - - new options "retry", "forever", and "intervall" - - option "fork" for address TCP improves `gender changer� - - options "sigint", "sigquit", and "sighup" control passing of signals to - sub process (thanks to David Shea who contributed to this issue) - - readline takes respect to the prompt issued by the peer address - - options "prompt" and "noprompt" allow to override readline's new - default behaviour - - readline supports invisible password with option "noecho" - - socat option -lp allows to set hostname in log output - - socat option -lu turns on microsecond resolution in log output - - -corrections: - before reading available data, check if writing on other channel is - possible - - tcp6, udp6: support hostname specification (not only IP address), and - map IP4 names to IP6 addresses - - openssl client checks server certificate per default - - support unidirectional communication with exec/system subprocess - - try to restore original terminal settings when terminating - - test.sh uses tmp dir /tmp/$USER/$$ instead of /tmp/$$ - - socks4 failed on platforms where long does not have 32 bits - (thanks to Peter Palfrader and Thomas Seyrat) - - hstrerror substitute wrote wrong messages (HP-UX, Solaris) - - proxy error message was truncated when answer contained multiple spaces - - -porting: - compiles with AIX xlc, HP-UX cc, Tru64 cc (but might not link) - -####################### V 1.3.2.2: - -corrections: - PROXY CONNECT failed when the status reply from the proxy server - contained more than one consecutive spaces. Problem reported by - Alexandre Bezroutchko - - do not SIGSEGV when proxy address fails to resolve server name - - udp-listen failed on systems where AF_INET != SOCK_DGRAM (e.g. SunOS). - Problem reported by Christoph Schittel - - test.sh only tests available features - - added missing IP and TCP options in filan analyzer - - do not apply stdio address options to both directions when in - unidirectional mode - - on systems lacking /dev/*random and egd, provide (weak) entropy from - libc random() - - -porting: - changes for HP-UX (VREPRINT, h_NETDB_INTERNAL) - - compiles on True64, FreeBSD (again), NetBSD, OpenBSD - - support for long long as st_ino type (Cygwin 1.5) - - compile on systems where pty can not be featured - -####################### V 1.3.2.1: - -corrections: - "final" solution for the ENOCHLD problem - - corrected "make strip" - - default gcc debug/opt is "-O" again - - check for /proc at runtime, even if configure found it - - src.rpm accidently supported SuSE instead of RedHat - -####################### V 1.3.2.0: - -new features: - option "nofork" connects an exec'd script or program directly - to the file descriptors of the other address, circumventing the socat - transfer engine - - support for files >2GB, using ftruncate64(), lseek64(), stat64() - - filan has new "simple" output style (filan -s) - - -porting: - options "binary" and "text" for controlling line termination on Cygwin - file system access (hint from Yang Wu-Zhou) - - fix by Yang Wu-Zhou for the Cygwin "No Children" problem - - improved support for OSR: _SVID3; no IS_SOCK, no F_GETOWN (thanks to - John DuBois) - - minor corrections to avoid warnings with gcc 3 - - -further corrections and minor improvements: - configure script is generated with autoconf 2.57 (no longer 2.52) - - configure passes CFLAGS to Makefile - - option -??? for complete list of address options and their short forms - - program name in syslog messages is derived from argv[0] - - SIGHUP now prints notice instead of error - - EIO during read of pty now gives Notice instead of Error, and - triggers EOF - - use of hstrerror() for printing resolver error messages - - setgrent() got required endgrent() - -####################### V 1.3.1.0: - -new features: - integration of Wietse Venema's tcpwrapper library (libwrap) - - with "proxy" address, option "resolve" controls if hostname or IP - address is sent in request - - option "lowport" establishes limited authorization for TCP and UDP - connections - - improvement of .spec file for RPM creation (thanks to Gerd v. Egidy) - An accompanying change in the numbering scheme results in an - incompatibility with earlier socat RPMs! - - -solved problems and bugs: - PROBLEM: socat daemon terminated when the address of a connecting - client did not match range option value instead of continue listening - SOLVED: in this case, print warning instead of error to keep daemon - active - - PROBLEM: tcp-listen with fork sometimes left excessive number of zombie - processes - SOLVED: dont assume that each exiting child process generates SIGCHLD - - when converting CRNL to CR, socat converted to NL - - -further corrections: - configure script now disables features that depend on missing files - making it more robust in "unsupported" environments - - server.pem permissions corrected to 600 - - "make install" now does not strip; use "make strip; make install" - if you like strip (suggested by Peter Bray) - -####################### V 1.3.0.1: - -solved problems and bugs: - PROBLEM: OPENSSL did not apply tcp, ip, and socket options - SOLVED: OPENSSL now correctly handles the options list - - PROBLEM: CRNL to NL and CRNL to CR conversions failed when CRNL crossed - block boundary - SOLVED: these conversions now simply strip all CR's or NL's from input - stream - - -porting: - SunOS ptys now work on x86, too (thanks to Peter Bray) - - configure looks for freeware libs in /pkgs/lib/ (thanks to Peter Bray) - - -further corrections: - added WITH_PROXY value to -V output - - added compile dependencies of WITH_PTY and WITH_PROXY - - -?? did not print option group of proxy options - - corrected syntax for bind option in docu - - corrected an issue with stdio in unidirectional mode - - options socksport and proxyport support service names - - ftp.sh script supports proxy address - - man page no longer installed with execute permissions (thanks to Peter - Bray) - - fixed a malloc call bug that could cause SIGSEGV or false "out of - memory" errors on EXEC and SYSTEM, depending on program name length and - libc. - -####################### V 1.3.0.0: - -new features: - proxy connect with optional proxy authentication - - combined hex and text dump mode, credits to Gregory Margo - - address pty applies options user, group, and perm to device - - -solved problems and bugs: - PROBLEM: option reuseport was not applied (BSD, AIX) - SOLVED: option reuseport now in phase PASTSOCKET instead of PREBIND, - credits to Jean-Baptiste Marchand - - PROBLEM: ignoreeof with stdio was ignored - SOLVED: ignoreeof now works correctly with address stdio - - PROBLEM: ftp.sh did not use user supplied password - SOLVED: ftp.sh now correctly passes password from command line - - PROBLEM: server.pem had expired - SOLVED: new server.pem valid for ten years - - PROBLEM: socks notice printed wrong port on some platforms - SOLVED: socks now uses correct byte-order for port number in notice - - -further corrections: - option name o_trunc corrected to o-trunc - - combined use of -u and -U is now detected and prevented - - made message system a little more robust against format string attacks - - -####################### V 1.2.0.0: - -new features: - address pty for putting socat behind a new pseudo terminal that may - fake a serial line, modem etc. - - experimental openssl integration - (it does not provide any trust between the peers because is does not - check certificates!) - - options flock-ex, flock-ex-nb, flock-sh, flock-sh-nb to control all - locking mechanism provided by flock() - - options setsid and setpgid now available with all address types - - option ctty (controlling terminal) now available for all TERMIOS - addresses - - option truncate (a hybrid of open(.., O_TRUNC) and ftruncate()) is - replaced by options o-trunc and ftruncate=offset - - option sourceport now available with TCP and UDP listen addresses to - restrict incoming client connections - - unidirectional mode right-to-left (-U) - - -solved problems and bugs: - PROBLEM: addresses without required parameters but an option containing - a '/' were incorrectly interpreted as implicit GOPEN address - SOLVED: if an address does not have ':' separator but contains '/', - check if the slash is before the first ',' before assuming - implicit GOPEN. - - -porting: - ptys under SunOS work now due to use of stream options - - -further corrections: - with -d -d -d -d -D, don't print debug info during file analysis - - -####################### V 1.1.0.1: - -new features: - .spec file for RPM generation - - -solved problems and bugs: - PROBLEM: GOPEN on socket did not apply option unlink-late - SOLUTION: GOPEN for socket now applies group NAMED, phase PASTOPEN - options - - PROBLEM: with unidirectional mode, an unnecessary close timeout was - applied - SOLUTION: in unidirectional mode, terminate without wait time - - PROBLEM: using GOPEN on a unix domain socket failed for datagram - sockets - SOLUTION: when connect() fails with EPROTOTYPE, use a datagram socket - - -further corrections: - - open() flag options had names starting with "o_", now corrected to "o-" - - in docu, *-listen addresses were called *_listen - - address unix now called unix-connect because it does not handle unix - datagram sockets - - in test.sh, apply global command line options with all tests - - -####################### V 1.1.0.0: - -new features: - regular man page and html doc - thanks to kromJx for prototype - - new address type "readline", utilizing GNU readline and history libs - - address option "history-file" for readline - - new option "dash" to "exec" address that allows to start login shells - - syslog facility can be set per command line option - - new address option "tcp-quickack", found in Linux 2.4 - - option -g prevents option group checking - - filan and procan can print usage - - procan prints rlimit infos - - -solved problems and bugs: - PROBLEM: raw IP socket SIGSEGV'ed when it had been shut down. - SOLVED: set eof flag of channel on shutdown. - - PROBLEM: if channel 2 uses a single non-socket FD in bidirectional mode - and has data available while channel 1 reaches EOF, the data is - lost. - SOLVED: during one loop run, first handle all data transfers and - _afterwards_ handle EOF. - - PROBLEM: despite to option NONBLOCK, the connect() call blocked - SOLVED: option NONBLOCK is now applied in phase FD instead of LATE - - PROBLEM: UNLINK options issued error when file did not exist, - terminating socat - SOLVED: failure of unlink() is only warning if errno==ENOENT - - PROBLEM: TCP6-LISTEN required numeric port specification - SOLVED: now uses common TCP service resolver - - PROBLEM: with PIPE, wrong FDs were shown for data transfer loop - SOLVED: retrieval of FDs now pays respect to PIPE pecularities - - PROBLEM: using address EXEC against an address with IGNOREEOF, socat - never terminated - SOLVED: corrected EOF handling of sigchld - - -porting: - MacOS and old AIX versions now have pty - - flock() now available on Linux (configure check was wrong) - - named pipe were generated using mknod(), which requires root under BSD - now they are generated using mkfifo - - -further corrections: - lots of address options that were "forgotten" at runtime are now - available - - option BINDTODEVICE now also called SO-BINDTODEVICE, IF - - "make install" now installs binaries with ownership 0:0 - - -####################### V 1.0.4.2: - -solved problems and bugs: - PROBLEM: EOF of one stream caused close of other stream, giving it no - chance to go down regularly - SOLVED: EOF of one stream now causes shutdown of write part of other - stream - - PROBLEM: sending mail via socks address to qmail showed that crlf - option does not work - SOLVED: socks address applies PH_LATE options - - PROBLEM: in debug mode, no info about socat and platform was issued - SOLVED: print socat version and uname output in debug mode - - PROBLEM: invoking socat with -t and no following parameters caused - SIGSEGV - SOLVED: -t and -b now check next argv entry - - PROBLEM: when opening of logfile (-lf) failed, no error was reported - and no further messages were printed - SOLVED: check result of fopen and print error message if it failed - -new features: - address type UDP-LISTEN now supports option fork: it internally applies - socket option SO_REUSEADDR so a new UDP socket can bind to port after - `accepting� a connection (child processes might live forever though) - (suggestion from Damjan Lango) - - -####################### V 1.0.4.1: - -solved problems and bugs: - PROB: assert in libc caused an endless recursion - SOLVED: no longer catch SIGABRT - - PROB: socat printed wrong verbose prefix for "right to left" packets - SOLVED: new parameter for xiotransfer() passes correct prefix - -new features: - in debug mode, socat prints its command line arguments - in verbose mode, escape special characters and replace unprintables - with '.'. Patch from Adrian Thurston. - - -####################### V 1.0.4.0: - -solved problems and bugs: - Debug output for lstat and fstat said "stat" - -further corrections: - FreeBSD now includes libutil.h - -new features: - option setsid with exec/pty - option setpgid with exec/pty - option ctty with exec/pty - TCP V6 connect test - gettimeofday in sycls.c (no use yet) - -porting: - before Gethostbyname, invoke inet_aton for MacOSX - - -####################### V 1.0.3.0: - -solved problems and bugs: - - PROB: test 9 of test.sh (echo via file) failed on some platforms, - socat exited without error message - SOLVED: _xioopen_named_early(): preset statbuf.st_mode with 0 - - PROB: test 17 hung forever - REASON: child death before select loop did not result in EOF - SOLVED: check of existence of children before starting select loop - - PROB: test 17 failed - REASON: child dead triggered EOF before last data was read - SOLVED: after child death, read last data before setting EOF - - PROB: filan showed that exec processes incorrectly had fd3 open - REASON: inherited open fd3 from main process - SOLVED: set CLOEXEC flag on pty fd in main process - - PROB: help printed "undef" instead of group "FORK" - SOLVED: added "FORK" to group name array - - PROB: fatal messages did not include severity classifier - SOLVED: added "F" to severity classifier array - - PROB: IP6 addresses where printed incorrectly - SOLVED: removed type casts to unsigned short * - -further corrections: - socat catches illegal -l modes - corrected error message on setsockopt(linger) - option tabdly is of type uint - correction for UDP over IP6 - more cpp conditionals, esp. for IP6 situations - better handling of group NAMED options with listening UNIX sockets - applyopts2 now includes last given phase - corrected option group handling for most address types - introduce dropping of unappliable options (dropopts, dropopts2) - gopen now accepts socket and unix-socket options - exec and system now accept all socket and termios options - child process for exec and system addresses with option pty - improved descriptions and options for EXAMPLES - printf format for file mode changed to "0%03o" with length spec. - added va_end() in branch of msg() - changed phase of lock options from PASTOPEN to FD - support up to four early dying processes - -structural changes: - xiosysincludes now includes sysincludes.h for non xio files - -new features: - option umask - CHANGES file - TYPE_DOUBLE, u_double - OFUNC_OFFSET - added getsid(), setsid(), send() to sycls - procan prints sid (session id) - mail.sh gets -f (from) option - new EXAMPLEs for file creation - gatherinfo.sh now tells about failures - test.sh can check for much more address/option combinations - -porting: - ispeed, ospeed for termios on FreeBSD - getpgid() conditional for MacOS 10 - added ranlib in Makefile.in for MacOS 10 - disable pty option if no pty mechanism is available (MacOS 10) - now compiles and runs on MacOS 10 (still some tests fail) - setgroups() conditional for cygwin - sighandler_t defined conditionally - use gcc option -D_GNU_SOURCE diff --git a/EXAMPLES b/EXAMPLES index 51b10ff..9ace4c4 100644 --- a/EXAMPLES +++ b/EXAMPLES @@ -67,7 +67,7 @@ $ socat \ TCP-LISTEN:8000,crlf \ SYSTEM:"echo HTTP/1.0 200; echo Content-Type\: text/plain; echo; cat" -// A less primitive HTTP echo server that sends back not only the reqest but +// A less primitive HTTP echo server that sends back not only the request but // also server and client address and port. Might have portability issues with // echo $ socat -T 1 -d -d \ @@ -131,7 +131,7 @@ $ socat \ /////////////////////////////////////////////////////////////////////////////// // Intrusion testing -// Found an XWindow Server behind IP filters with FTP data hole? (you are +// Found an X-Window Server behind IP filters with FTP data hole? (you are // lucky!) // prepare your host: # rm -f /tmp/.X11-unix/X1 @@ -241,7 +241,7 @@ $ socat - /tmp/postoffice // Uses of filan // See what your operating system opens for you $ filan -// or if that was too detailled +// or if that was too detailed $ filan -s // See what file descriptors are passed via exec function $ socat - EXEC:"filan -s",nofork @@ -342,7 +342,7 @@ socat \ // three main versions for entering password: // 1) from your TTY; have 10 seconds to enter password: (sleep 10; echo "ls"; sleep 1) |socat - EXEC:'ssh server',pty -// 2) from XWindows (DISPLAY !); again 10 seconds +// 2) from X-Windows (DISPLAY !); again 10 seconds (sleep 10; echo "ls"; sleep 1) |socat - EXEC:'ssh server',pty,setsid // 3) from script (sleep 5; echo PASSWORD; echo ls; sleep 1) |./socat - EXEC:'ssh server',pty,setsid,ctty diff --git a/FAQ b/FAQ index 51d8c1b..d3845eb 100644 --- a/FAQ +++ b/FAQ @@ -60,7 +60,7 @@ Q: When I specify a dual address (two partial addresses linked with "!!") on the command line, I get some message "event not found", and my shell history has the line truncated. Not even protecting the '!'s with '\' helps. -A: '!' is appearently used by your shell as history expansion character. Say +A: '!' is apparently used by your shell as history expansion character. Say "set +H" and add this line to your (bash) profile. diff --git a/Makefile.in b/Makefile.in index 631d31d..6187393 100644 --- a/Makefile.in +++ b/Makefile.in @@ -80,7 +80,7 @@ SHFILES = socat-chain.sh socat-mux.sh socat-broker.sh \ daemon.sh mail.sh ftp.sh readline.sh \ socat_buildscript_for_android.sh TESTFILES = test.sh socks4echo.sh proxyecho.sh readline-test.sh \ - proxy.sh socks4a-echo.sh + proxy.sh socks4a-echo.sh socks5server-echo.sh all: progs doc diff --git a/PORTING b/PORTING index 0571bf7..2cbb8f1 100644 --- a/PORTING +++ b/PORTING @@ -51,7 +51,7 @@ ACTIVE PHASE: . xioopts.h: enum e_optcode (sorted numerically/alphabetically by name) . xio-*.c: select the appropriate address file (e.g., xio-tcp.c for TCP-options) and make a record of type struct optdesc: opt_newoption - . xio-*.h: the declation of struct optdesc + . xio-*.h: the declaration of struct optdesc . xioopts.c: add records to struct optname optionnames for all appropriate names (sorted strictly ASCII for binary search) . filan.c: add the option to the appropriate array (sockopts, ipopts, diff --git a/README b/README index c48c095..da6f64a 100644 --- a/README +++ b/README @@ -58,18 +58,25 @@ Rocky 9 Cygwin 10.0 -install -------- +build +----- + +You need at least gcc and make. +A few libraries are required for full features: +Debian: libssl-dev libreadline-dev libwrap0-dev +Red Hat: openssl-devel readline-devel tcp_wrappers-libs +Arch Linux: openssl readline + Get the tarball and extract it: tar xzf socat.tar.gz - cd socat-1.8.0.2 + cd socat-1.8.0.3 ./configure make su make install # installs socat, filan, and procan in /usr/local/bin -For compiling socat, gcc (or clang) is recommended. +For compiling socat, gcc or a compatible compiler (e.g. clang) is recommended. If gcc (or a compiler with similar front end) is not available, the configure script might fail to determine some features diff --git a/README.FIPS b/README.FIPS index 0452844..2b92ea0 100644 --- a/README.FIPS +++ b/README.FIPS @@ -29,7 +29,7 @@ initializes things so after a fork, the child must reinitialize. When the ssl code detects a forks occur and if FIPS mode was enabled, it reinitializes FIPS by disabling and then enabling it again. -To produce Davids enviroment, do the following: +To produce Davids environment, do the following: To build openssl download OpenSSL 0.9.7j-fips-dev from http://www.openssl.org/source/OpenSSL-fips-1.0.tar.gz diff --git a/SECURITY b/SECURITY index 0e10075..27f295a 100644 --- a/SECURITY +++ b/SECURITY @@ -24,7 +24,7 @@ avoid accessing files in world-writable directories like /tmp * When using socat with system, exec, or in a shell script, know what you do -* With system and exec, use absolute pathes or set the path option +* With system and exec, use absolute paths or set the path option * When starting programs with socat, consider using the chroot option (this requires root, so use the substuser option too). diff --git a/VERSION b/VERSION index 2b16796..12355b9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.8.0.2" +"1.8.0.3" diff --git a/compat.h b/compat.h index 72e73c7..ecfa27c 100644 --- a/compat.h +++ b/compat.h @@ -98,6 +98,10 @@ typedef int sig_atomic_t; # define SOL_IPV6 IPPROTO_IPV6 #endif +#ifndef EAI_NODATA +# define EAI_NODATA 7 /* for old FreeBSD */ +#endif + #define F_uint8_t "%hu" #define F_uint8_x "%02hx" #define F_int8_t "%hd" diff --git a/config.h.in b/config.h.in index 682913e..cd2fdeb 100644 --- a/config.h.in +++ b/config.h.in @@ -162,6 +162,12 @@ /* Define if you have the clock_gettime function */ #undef HAVE_CLOCK_GETTIME +/* Define if you have the getresuid function */ +#undef HAVE_GETRESUID + +/* Define if you have the getresgid function */ +#undef HAVE_GETRESGID + /* Define if you have the strtoll function */ #undef HAVE_STRTOLL @@ -282,6 +288,9 @@ /* Define if you have the <linux/if_tun.h> header file. */ #undef HAVE_LINUX_IF_TUN_H +/* Define if you have the <netinet/dccp.h> header file. */ +#undef HAVE_NETINET_DCCP_H + /* Define if you have the <linux/dccp.h> header file. */ #undef HAVE_LINUX_DCCP_H @@ -333,6 +342,9 @@ /* Define if you have the <readline/history.h> header file. */ #undef HAVE_READLINE_HISTORY_H +/* Define if you have the <mqueue.h> header file. */ +#undef HAVE_MQUEUE_H + /* Define if you have the readline library. */ #undef HAVE_LIBREADLINE diff --git a/configure.ac b/configure.ac index b0227ec..f36a27b 100644 --- a/configure.ac +++ b/configure.ac @@ -39,7 +39,7 @@ AC_PROG_RANLIB AC_SUBST(AR) AC_CHECK_PROG(AR, ar, ar, gar) # -# we need to explicitely call this here; otherwise, with --disable-libwrap we +# we need to explicitly call this here; otherwise, with --disable-libwrap we # fail AC_LANG_COMPILER_REQUIRE() @@ -409,21 +409,33 @@ AC_ARG_ENABLE(dccp, [ --disable-dccp disable DCCP support], [AC_MSG_RESULT(yes); WITH_DCCP=1 ]) if test -n "$WITH_DCCP"; then -AC_MSG_CHECKING(for IPPROTO_DCCP) -AC_CACHE_VAL(sc_cv_define_ipproto_dccp, -[AC_TRY_COMPILE([#include <sys/types.h> -#include <netinet/in.h>], -[IPPROTO_DCCP;], -[sc_cv_define_ipproto_dccp=yes], -[sc_cv_define_ipproto_dccp=no])]) -AC_MSG_RESULT($sc_cv_define_ipproto_dccp) -if test $sc_cv_define_ipproto_dccp = yes; then - AC_DEFINE(WITH_DCCP) + AC_CHECK_HEADER(netinet/dccp.h, + AC_DEFINE(HAVE_NETINET_DCCP_H)) AC_CHECK_HEADER(linux/dccp.h, AC_DEFINE(HAVE_LINUX_DCCP_H)) -else - AC_MSG_WARN([IPPROTO_DCCP undefined, disabling DCCP support]) fi +if test -n "$WITH_DCCP"; then + AC_MSG_CHECKING(for IPPROTO_DCCP) + AC_CACHE_VAL(sc_cv_define_ipproto_dccp, + [AC_TRY_COMPILE([#include <sys/types.h> + #include <netinet/in.h>], + [IPPROTO_DCCP;], + [sc_cv_define_ipproto_dccp=yes], + [sc_cv_define_ipproto_dccp=no; WITH_DCCP=])]) + AC_MSG_RESULT($sc_cv_define_ipproto_dccp) +fi +if test -n "$WITH_DCCP"; then + AC_MSG_CHECKING(for SOCK_DCCP) + AC_CACHE_VAL(sc_cv_define_sock_dccp, + [AC_TRY_COMPILE([#include <sys/types.h> + #include <netinet/in.h>], + [SOCK_DCCP;], + [sc_cv_define_sock_dccp=yes], + [sc_cv_define_sock_dccp=no; WITH_DCCP=])]) + AC_MSG_RESULT($sc_cv_define_sock_dccp) +fi +if test -n "$WITH_DCCP"; then + AC_DEFINE(WITH_DCCP) fi AC_MSG_CHECKING(whether to include vsock support) @@ -489,6 +501,13 @@ AC_ARG_ENABLE(posixmq, [ --disable-posixmq disable POSIX MQ support], *) WITH_POSIXMQ=1; AC_MSG_RESULT(yes);; esac], [WITH_POSIXMQ=1; AC_MSG_RESULT(yes)]) +if test "$WITH_POSIXMQ"; then + AC_CHECK_HEADERS(mqueue.h) + if test "x$ac_cv_header_mqueue_h" != xyes; then + AC_MSG_WARN([Header mqueue.h not found, disabling POSIX MQ]) + WITH_POSIXMQ= + fi +fi if test "$WITH_POSIXMQ"; then case "`uname`" in Linux) AC_DEFINE(WITH_POSIXMQ) @@ -652,23 +671,16 @@ if test -n "$WITH_OPENSSL"; then AC_CACHE_VAL(sc_cv_have_openssl_ssl_h, [AC_TRY_COMPILE([#include <openssl/ssl.h>],[;], [sc_cv_have_openssl_ssl_h=yes; OPENSSL_BASE=""; ], - [sc_cv_have_openssl_ssl_h=no - if test "$OPENSSL_BASE"; then - Ds="$OPENSSL_BASE" - else - Ds="/sw /usr/local /opt/freeware /usr/sfw /usr/local/ssl" - fi - for D in $Ds; do - I="$D/include" - i="$I/openssl/ssl.h" - if test -r "$i"; then - #V_INCL="$V_INCL -I$I" - CPPFLAGS="$CPPFLAGS -I$I" - AC_MSG_NOTICE(found $i) - sc_cv_have_openssl_ssl_h=yes; OPENSSL_BASE="$D" - break; - fi - done]) + [ + # Another attempt to compile with OPENSSL_NO_KRB5 + AC_MSG_NOTICE(trying with -DOPENSSL_NO_KRB5) + CFLAGS_ORIG="$CFLAGS" + CFLAGS="$CFLAGS -DOPENSSL_NO_KRB5" + AC_TRY_COMPILE([#include <openssl/ssl.h>],[;], + [sc_cv_have_openssl_ssl_h=yes], + [sc_cv_have_openssl_ssl_h=no + CFLAGS="$CFLAGS_ORIG"]) + ]) ]) if test "$sc_cv_have_openssl_ssl_h" = "yes"; then AC_DEFINE(HAVE_OPENSSL_SSL_H) @@ -1722,6 +1734,8 @@ AC_CHECK_PROTOTYPE_LIB(gettimeofday) AC_CHECK_FUNC(clock_gettime, AC_DEFINE(HAVE_CLOCK_GETTIME), AC_CHECK_LIB(rt, clock_gettime, [LIBS="-lrt $LIBS"; AC_DEFINE(HAVE_CLOCK_GETTIME)])) +AC_CHECK_FUNCS(getresuid getresgid) + dnl Search for flock() # with Linux it's in libc, with AIX in libbsd AC_CHECK_FUNC(flock, AC_DEFINE(HAVE_FLOCK), @@ -2248,7 +2262,7 @@ AC_TRY_COMPILE([#include <resolv.h>], dnl "tcpd" "tcpwrappers" # on some platforms, raw linking with libwrap fails because allow_severity and -# deny_severity are not explicitely defined. Thus we put the libwrap part to +# deny_severity are not explicitly defined. Thus we put the libwrap part to # the end AC_MSG_CHECKING(whether to include libwrap support) AC_ARG_ENABLE(libwrap, [ --disable-libwrap disable libwrap support], @@ -2303,7 +2317,7 @@ int allow_severity,deny_severity;],[hosts_access(0)], AC_TRY_LINK([#include <sys/types.h> #include <tcpd.h> int allow_severity,deny_severity;],[hosts_access(0)], - [sc_cv_have_libwrap='yes'], + [sc_cv_have_libwrap='yes'], [sc_cv_have_libwrap='no']) ] ) diff --git a/doc/socat-genericsocket.html b/doc/socat-genericsocket.html index 0525696..2ad1440 100644 --- a/doc/socat-genericsocket.html +++ b/doc/socat-genericsocket.html @@ -10,7 +10,7 @@ <h2>Introduction</h2> <p>Beginning with version 1.7.0 socat provides means to freely control important aspects of socket handling. This allows to experiment with socket - types and protocols that are not explicitely implemented in socat. + types and protocols that are not explicitly implemented in socat. </p> <p>The related socat features fall into three major categories:<p> @@ -216,7 +216,7 @@ struct sockaddr_at { </p> <p>The address family component must be omitted from the socket address because - it is added by socat implicitely. The resulting hexadecimal representation of + it is added by socat implicitly. The resulting hexadecimal representation of the target socket address is therefore: </p> <tt>x40x00xff00xf3x00x0000000000000000</tt> @@ -287,7 +287,7 @@ struct sockaddr_at { and for bind and range options. The basis is the <tt>struct sockaddr_*</tt> for the respective address family that should be declared in the C include files. Please keep in mind that their first two bytes (<tt>sa_family</tt> and - on BSD -- <tt>sa_len</tt>) are implicitely prepended by socat.</p> +- <tt>sa_len</tt>) are implicitly prepended by socat.</p> <h4>Linux on 32bit Intel:</h4> diff --git a/doc/socat.yo b/doc/socat.yo index abfd991..106686a 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -313,6 +313,7 @@ label(ADDRESS_CREAT)dit(bf(tt(CREATE:<filename>))) if <filename> refers to a socket, this is an error.nl() Option groups: link(FD)(GROUP_FD),link(REG)(GROUP_REG),link(NAMED)(GROUP_NAMED) nl() Useful options: + link(mode)(OPTION_UMASK), link(mode)(OPTION_MODE), link(user)(OPTION_USER), link(group)(OPTION_GROUP), @@ -332,7 +333,7 @@ label(ADDRESS_DCCP_CONNECT)dit(bf(tt(DCCP-CONNECT:<host>:<port>)) (bf(tt(DCCP:<h link(connect-timeout)(OPTION_CONNECT_TIMEOUT), link(tos)(OPTION_TOS), link(dccp-set-ccid)(OPTION_DCCP_SET_CCID), - link(nonblock)(OPTION_NONBLOCK), + link(nonblock)(OPTION_O_NONBLOCK), link(sourceport)(OPTION_SOURCEPORT), link(retry)(OPTION_RETRY), link(readbytes)(OPTION_READBYTES)nl() @@ -583,7 +584,7 @@ label(ADDRESS_OPEN)dit(bf(tt(OPEN:<filename>))) Option groups: link(FD)(GROUP_FD),link(REG)(GROUP_REG),link(NAMED)(GROUP_NAMED),link(OPEN)(GROUP_OPEN) nl() Useful options: link(creat)(OPTION_O_CREAT), - link(excl)(OPTION_EXCL), + link(excl)(OPTION_O_EXCL), link(noatime)(OPTION_O_NOATIME), link(nofollow)(OPTION_NOFOLLOW), link(append)(OPTION_APPEND), @@ -747,7 +748,7 @@ label(ADDRESS_NAMED_PIPE)dit(bf(tt(PIPE:<filename>))) Option groups: link(FD)(GROUP_FD),link(NAMED)(GROUP_NAMED),link(OPEN)(GROUP_OPEN) nl() Useful options: link(rdonly)(OPTION_RDONLY), - link(nonblock)(OPTION_NONBLOCK), + link(nonblock)(OPTION_O_NONBLOCK), link(group)(OPTION_GROUP), link(user)(OPTION_USER), link(mode)(OPTION_MODE), @@ -773,50 +774,65 @@ label(ADDRESS_SOCKETPAIR)dit(bf(tt(SOCKETPAIR))) See also: link(unnamed pipe)(ADDRESS_UNNAMED_PIPE) label(ADDRESS_POSIXMQ_READ)dit(bf(tt(POSIXMQ-READ:/<mqueue>))) - Opens the specified POSIX message queue and reads messages (packets). It - keeps the boundaries.nl() + Opens or creates the specified POSIX message queue and reads messages + (packets). It keeps the packet boundaries.nl() This is a read-only address, see options link(-u)(option_u) and link(-U)(option_U) and link(dual addresses)(ADDRESS_DUAL).nl() Socat() provides this address type only on Linux because POSIX MQ is based on UNIX filedescriptors there.nl() - This feature is new in version 1.8.0.0 and might change in the future, - therefore it is link(experimental)(option_experimental).nl() Useful options: link(posixmq-priority)(OPTION_POSIXMQ_PRIORITY), link(unlink-early)(OPTION_UNLINK_EARLY), - link(unlink-close)(OPTION_UNLINK_CLOSE) + link(unlink-close)(OPTION_UNLINK_CLOSE), + link(o-nonblock)(OPTION_O_NONBLOCK), + link(o-creat)(OPTION_O_CREAT), + link(o-excl)(OPTION_O_EXCL), + link(umask)(OPTION_UMASK) label(ADDRESS_POSIXMQ_RECEIVE)dit(bf(tt(POSIXMQ-RECEIVE:/<mqueue>))) dit(bf(tt(POSIXMQ-RECV:/<mqueue>))) - Opens the specified POSIX message queue and reads one message (packet).nl() + Opens or creates the specified POSIX message queue and reads one message + (packet).nl() This is a read-only address. See link(POSIXMQ-READ)(ADDRESS_POSIXMQ_READ) for more info.nl() Example: link(POSIX MQ recv with fork)(EXAMPLE_POSIXMQ_RECV_FORK)nl() - This feature is link(experimental)(option_experimental).nl() Useful options: link(posixmq-priority)(OPTION_POSIXMQ_PRIORITY), link(fork)(OPTION_FORK), link(max-children)(OPTION_MAX_CHILDREN), link(unlink-early)(OPTION_UNLINK_EARLY), - link(unlink-close)(OPTION_UNLINK_CLOSE) + link(unlink-close)(OPTION_UNLINK_CLOSE), + link(o-creat)(OPTION_O_CREAT), + link(o-excl)(OPTION_O_EXCL), + link(umask)(OPTION_UMASK) label(ADDRESS_POSIXMQ_SEND)dit(bf(tt(POSIXMQ-SEND:/<mqueue>))) - Opens the specified POSIX message queue and writes messages (packets).nl() + Opens or creates the specified POSIX message queue and writes messages + (packets).nl() This is a write-only address. See link(POSIXMQ-READ)(ADDRESS_POSIXMQ_READ) for more info.nl() (link(Example)(EXAMPLE_POSIXMQ_SEND))nl() - This feature is link(experimental)(option_experimental).nl() Useful options: link(posixmq-priority)(OPTION_POSIXMQ_PRIORITY), + link(posixmq-flush)(OPTION_POSIXMQ_FLUSH), link(fork)(OPTION_FORK), link(max-children)(OPTION_MAX_CHILDREN), link(unlink-early)(OPTION_UNLINK_EARLY), - link(unlink-close)(OPTION_UNLINK_CLOSE) + link(unlink-close)(OPTION_UNLINK_CLOSE), + link(o-creat)(OPTION_O_CREAT), + link(o-excl)(OPTION_O_EXCL), + link(umask)(OPTION_UMASK) + +label(ADDRESS_POSIXMQ_WRITE)dit(bf(tt(POSIXMQ-WRITE:/<mqueue>))) + Does the same as link(POSIXMQ-SEND)(ADDRESS_POSIXMQ_SEND). label(ADDRESS_POSIXMQ_BIDIRECTIONAL)dit(bf(tt(POSIXMQ-BIDIRECTIONAL:/mqueue))) - Opens the specified POSIX message queue and writes and reads messages - (packet). This is probably rarely useful but has been implemented for - functional completeness. +dit(bf(tt(POSIXMQ:/mqueue))) + Opens or creates the specified POSIX message queue in read and/or write mode + depending on context, then reads and/or writes messages (packets). + In bidirectional mode this is just another echo service.nl() + See link(POSIXMQ-READ)(ADDRESS_POSIXMQ_READ) and + link(POSIXMQ-SEND)(ADDRESS_POSIXMQ_SEND) for more info. label(ADDRESS_PROXY_CONNECT)dit(bf(tt(PROXY:<proxy>:<hostname>:<port>))) Connects to an HTTP proxy server on port 8080 using TCP/IP version 4 or 6 @@ -882,7 +898,7 @@ label(ADDRESS_SCTP_CONNECT)dit(bf(tt(SCTP-CONNECT:<host>:<port>))) link(mtudiscover)(OPTION_MTUDISCOVER), link(sctp-maxseg)(OPTION_SCTP_MAXSEG), link(sctp-nodelay)(OPTION_SCTP_NODELAY), - link(nonblock)(OPTION_NONBLOCK), + link(nonblock)(OPTION_O_NONBLOCK), link(sourceport)(OPTION_SOURCEPORT), link(retry)(OPTION_RETRY), link(readbytes)(OPTION_READBYTES)nl() @@ -1103,11 +1119,11 @@ label(ADDRESS_SOCKS4A)dit(bf(tt(SOCKS4A:<socks-server>:<host>:<port>))) Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(SOCKS4)(GROUP_SOCKS),link(RETRY)(GROUP_RETRY) nl() label(ADDRESS_SOCKS5_CONNECT)dit(bf(tt(SOCKS5-CONNECT:<socks-server>:<socks-port>:<target-host>:<target-port>))) +dit(bf(tt(SOCKS5-CONNECT:<socks-server>:<target-host>:<target-port>))) Connects via <socks-server> [link(IP address)(TYPE_IP_ADDRESS)] to <target-host> [link(IPv4 address)(TYPE_IPV4_ADDRESS)] on <target-port> [link(TCP service)(TYPE_TCP_SERVICE)], using socks version 5 protocol over TCP. Currently no authentication mechanism is provided.nl() - This address type is experimental.nl() Option groups: link(FD)(GROUP_FD), link(SOCKET)(GROUP_SOCKET), link(IP4)(GROUP_IP4), link(IP6)(GROUP_IP6), link(TCP)(GROUP_TCP), link(CHILD)(GROUP_CHILD), link(RETRY)(GROUP_RETRY)nl() Useful options: link(socksport)(OPTION_SOCKSPORT), @@ -1122,10 +1138,11 @@ label(ADDRESS_SOCKS5_CONNECT)dit(bf(tt(SOCKS5-CONNECT:<socks-server>:<socks-port link(TCP)(ADDRESS_TCP_CONNECT) label(ADDRESS_SOCKS5_LISTEN)dit(bf(tt(SOCKS5-LISTEN:<socks-server>:<socks-port>:<listen-host>:<listen-port>))) +dit(bf(tt(SOCKS5-LISTEN:<socks-server>:<listen-host>:<listen-port>))) Connects to <socks-server> [link(IP address)(TYPE_IP_ADDRESS)] using socks version 5 protocol over TCP and makes it listen for incoming connections on <listen-port> [link(TCP service)(TYPE_TCP_SERVICE)], binding to <-listen-host> [link(IPv4 address)(TYPE_IPV4_ADDRESS)] - Currently not authentication mechanism is provided. This address type is experimental. + Currently not authentication mechanism is provided.nl() Option groups: link(FD)(GROUP_FD), link(SOCKET)(GROUP_SOCKET), link(IP4)(GROUP_IP4), link(IP6)(GROUP_IP6), link(TCP)(GROUP_TCP), link(CHILD)(GROUP_CHILD), link(RETRY)(GROUP_RETRY)nl() Useful options: link(sourceport)(OPTION_SOURCEPORT), @@ -1233,7 +1250,7 @@ label(ADDRESS_TCP_CONNECT)dit(bf(tt(TCP:<host>:<port>))) link(mtudiscover)(OPTION_MTUDISCOVER), link(mss)(OPTION_MSS), link(nodelay)(OPTION_TCP_NODELAY), - link(nonblock)(OPTION_NONBLOCK), + link(nonblock)(OPTION_O_NONBLOCK), link(readbytes)(OPTION_READBYTES)nl() See also: link(TCP4)(ADDRESS_TCP4_CONNECT), @@ -1290,7 +1307,7 @@ label(ADDRESS_TCP6_LISTEN)dit(bf(tt(TCP6-LISTEN:<port>))) link(ipv6only)(OPTION_IPV6_V6ONLY)nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(RETRY)(GROUP_RETRY) nl() label(ADDRESS_TUN)dit(bf(tt(TUN[:<if-addr>/<bits>]))) - Creates a Linux TUN/TAP device and optionally assignes it the address and + Creates a Linux TUN/TAP device and optionally assigns it the address and netmask given by the parameters. The resulting network interface is almost ready for use by other processes; socat serves its "wire side". This address requires read and write access to the tunnel cloning device, usually @@ -1418,7 +1435,8 @@ label(ADDRESS_UDP_SENDTO)dit(bf(tt(UDP-SENDTO:<host>:<port>))) link(pf)(OPTION_PROTOCOL_FAMILY). It sends packets to and receives packets from that peer socket only. This address effectively implements a datagram client. - It works well with socat UDP-RECVFROM and UDP-RECV address peers.nl() + It works well with socat UDP-RECVFROM and UDP-RECV address peers. + When the peer might send data first, link(UDP-DATAGRAM)(ADDRESS_UDP_DATAGRAM) is preferable.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6) nl() Useful options: link(ttl)(OPTION_TTL), @@ -1456,7 +1474,8 @@ label(ADDRESS_UDP_RECVFROM)dit(bf(tt(UDP-RECVFROM:<port>))) label(NOTE_RECVFROM)Note: When the second address fails before entering the transfer loop the packet is dropped. Use option link(retry)(OPTION_RETRY) or link(forever)(OPTION_FOREVER) on the second address to avoid data loss. - nl() + When you know the peer address, link(UDP-DATAGRAM)(ADDRESS_UDP_DATAGRAM) is + preferable.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE) nl() Useful options: link(fork)(OPTION_FORK), @@ -1839,8 +1858,10 @@ label(OPTION_MODE)dit(bf(tt(mode=<mode>))) system calls, socat() uses the code(chmod()) system call after opening the filesystem entry or binding to the unixdomain() socket (race condition!). Otherwise, socat() sets the mode of the stream - using code(fchmod()). - These calls might require ownership or root privilege. + using code(fchmod()) which, btw, might not have any effect.nl() + These calls might require ownership or root privilege.nl() + Note: this option can only tighten the permissions implied by processes + umask. See option link(umask)(OPTION_UMASK) to loosen permissions. label(OPTION_PERM_LATE)dit(bf(tt(perm-late=<mode>))) Sets the permissions of the fd to value <mode> [link(mode_t)(TYPE_MODE_T)] using the code(fchmod()) system call after @@ -1852,7 +1873,7 @@ label(OPTION_APPEND)dit(bf(tt(append[=<bool>]))) socat() uses the code(O_APPEND) flag with the code(open()) system call (link(example)(EXAMPLE_OPTION_APPEND)). Otherwise, socat() applies the code(fcntl(fd, F_SETFL, O_APPEND)) call. -label(OPTION_NONBLOCK)dit(bf(tt(nonblock[=<bool>]))) +label(OPTION_O_NONBLOCK)dit(bf(tt(nonblock[=<bool>]))) Tries to open or use file in nonblocking mode. Its only effects are that the code(connect()) call of TCP addresses does not block, and that opening a named pipe for reading does not block. @@ -1987,13 +2008,13 @@ E.g., option `creat' sets the code(O_CREAT) flag. When the used address does not use code(open()) (e.g.STDIO), the code(fcntl(..., F_SETFL, ...)) call is used instead.nl() See also options link(append)(OPTION_APPEND) and -link(nonblock)(OPTION_NONBLOCK). +link(nonblock)(OPTION_O_NONBLOCK). startdit() label(OPTION_O_CREAT)dit(bf(tt(creat[=<bool>]))) Creates the file if it does not exist (link(example)(EXAMPLE_OPTION_CREAT)). label(OPTION_DSYNC)dit(bf(tt(dsync[=<bool>]))) Blocks code(write()) calls until metainfo is physically written to media. -label(OPTION_EXCL)dit(bf(tt(excl[=<bool>]))) +label(OPTION_O_EXCL)dit(bf(tt(excl[=<bool>]))) With option creat, if file exists this is an error. label(OPTION_LARGEFILE)dit(bf(tt(largefile[=<bool>]))) On 32 bit systems, allows a file larger than 2^31 bytes. @@ -2108,8 +2129,9 @@ label(OPTION_CHDIR)dit(bf(tt(chdir=<filename>))) dit(bf(tt(cd=<filename>))) label(OPTION_UMASK)dit(bf(tt(umask=<mode>))) Sets the umask of the process to <mode> [link(mode_t)(TYPE_MODE_T)] before opening the address. Useful when file system entries are created or a shell - or program is invoked. Usually the value is specified as octal number.nl() - The processes tt(umask) value is inherited by child processes. + or program is invoked. Usually the value is specified as octal number with + leading '0'.nl() + The processes tt(umask) value is inherited by child processes.nl() Note: umask is an inverted value: creating a file with umask=0026 results in permissions 0640. enddit() @@ -2136,7 +2158,7 @@ label(OPTION_SETGID)dit(bf(tt(setgid=<group>))) processing the address. This call might require root privilege. Please note that this option does not drop other group related privileges. label(OPTION_SETGID_EARLY)dit(bf(tt(setgid-early=<group>))) - Like link(setgit)(OPTION_SETGID) but is performed before opening the address. + Like link(setgid)(OPTION_SETGID) but is performed before opening the address. label(OPTION_SETUID)dit(bf(tt(setuid=<user>))) Changes the link(<user>)(TYPE_USER) (owner) of the process after processing the address. This call might require root privilege. Please note that this @@ -2164,9 +2186,9 @@ label(OPTION_SETSID)dit(bf(tt(setsid))) Makes the process the leader of a new session (link(example)(EXAMPLE_OPTION_SETSID)). label(OPTION_NETNS)dit(bf(tt(netns=<net-namespace-name>))) Before opening the address it tries to switch to the named network namespace. - After opening the address it switches back to the previous namespace. - (link(Example with TCP forwarder)(EXAMPLE_OPTION_NETNS), - link(example with virtual network connection)(EXAMPLE_TUN_NETNS).nl() + After opening the address it switches back to the previous namespace + (link(example with TCP forwarder)(EXAMPLE_OPTION_NETNS), + link(example with virtual network connection)(EXAMPLE_TUN_NETNS)).nl() Only on Linux; requires root; use option tt(--experimental).nl() enddit() @@ -2189,7 +2211,7 @@ label(OPTION_NOECHO)dit(bf(tt(noecho=<pattern>))) Specifies a regular pattern for a prompt that prevents the following input line from being displayed on the screen and from being added to the history. The prompt is defined as the text that was output to the readline address - after the lastest newline character and before an input character was + after the last newline character and before an input character was typed. The pattern is a regular expression, e.g. "^[Pp]assword:.*$" or "([Uu]ser:|[Pp]assword:)". See NOEXPAND(regex(7)) for details. (link(example)(EXAMPLE_OPTION_NOECHO)) @@ -2368,7 +2390,7 @@ COMMENT(label(OPTION_SECURITYENCRYPTIONNETWORK)dit(bf(tt(securityencryptionnetwo COMMENT(label(OPTION_SECURITYENCRYPTIONTRANSPORT)dit(bf(tt(securityencryptiontransport))) Set the code(SO_SECURITY_ENCRYPTION_TRANSPORT) socket option.) COMMENT(label(OPTION_SIOCSPGRP)dit(bf(tt(siocspgrp=<pid_t>))) - Set the SIOCSPGRP with code(ioclt()) to enable SIGIO.) + Set the SIOCSPGRP with code(ioctl()) to enable SIGIO.) COMMENT(label(OPTION_USEIFBUFS)dit(bf(tt(useifbufs))) Set the code(SO_USE_IFBUFS) socket option.) label(OPTION_SO_TIMESTAMP)dit(bf(tt(so-timestamp))) @@ -2394,6 +2416,12 @@ label(OPTION_SETSOCKOPT_STRING)dit(bf(tt(setsockopt-string=<level>:<optname>:<op Like tt(setsockopt), but <optval> is a link(string)(TYPE_STRING). This string is passed to the function with trailing null character, and the length parameter is automatically derived from the data. +label(OPTION_SETSOCKOPT_SOCKET)dit(bf(tt(setsockopt-socket=<level>:<optname>:<optval>))) + Like tt(setsockopt), but is applied to the socket before other operations + (code(bind()), code(connect()), code(accept()), ...) +label(OPTION_SETSOCKOPT_CONNECTED)dit(bf(tt(setsockopt-connected=<level>:<optname>:<optval>))) + Like tt(setsockopt), but is applied only when the socket has been connected + by a code(connect()) or code(listen()) call. enddit() startdit()enddit()nl() @@ -2525,7 +2553,8 @@ dit(bf(tt(ipv6-join-source-group=<multicast-address:interface-index:source-addre IPv4 variant. The option takes the IP address of the multicast group, info about the desired network interface and the source IP address of the multicast traffic. The indices of active network interfaces can be shown - using the utility procan(). + using the utility procan().nl() + This feature is experimental. label(OPTION_IP_MULTICAST_IF) dit(bf(tt(ip-multicast-if=<hostname>))) Specifies hostname or address of the network interface to be used for @@ -2976,6 +3005,8 @@ label(OPTION_NOFORK)dit(bf(tt(nofork))) it() the first socat address cannot be OPENSSL or READLINE it() socat options -b, -t, -D, -l, -v, -x become useless it() for both addresses, options ignoreeof, cr, and crnl become useless + it() for both addresses, address specific end/shutdown handling (e.g., + graceful socket shutdown) and related options become useless it() for the second address (the one with option nofork), options append, metaCOMMENT(async,) cloexec, flock, user, group, mode, nonblock, perm-late, setlk, and setpgid cannot be applied. Some of these could be @@ -3345,7 +3376,7 @@ label(OPTION_OPENSSL_PSEUDO)dit(bf(tt(pseudo))) gathering daemon can be utilized, this option activates a mechanism for providing pseudo entropy. This is achieved by taking the current time in microseconds for feeding the libc pseudo random number generator with an - initial value. openssl is then feeded with output from NOEXPAND(random()) calls.nl() + initial value. openssl is then fed with output from NOEXPAND(random()) calls.nl() NOTE:This mechanism is not sufficient for generation of secure keys! label(OPTION_OPENSSL_COMPRESS)dit(bf(tt(compress))) Enable or disable the use of compression for a connection. Setting this to @@ -3490,6 +3521,15 @@ startdit() label(OPTION_POSIXMQ_PRIORITY)dit(bf(tt(posixmq-priority (mq-prio)))) Sets the priority of messages (packets) written to the queue, or the minimal priority of packet read from the queue. +label(OPTION_POSIXMQ_FLUSH)dit(bf(tt(posixmq-flush (mq-flush)))) + "Consumes" (drops) all messages currently in the queue before starting + transfers. +label(OPTION_POSIXMQ_MAXMSG)dit(bf(tt(posixmq-maxmsg (mq-maxmsg)))) + Sets the maxmsg parameter of the POSIX message queue when creating it.nl() + Note: This option applies only when the queue does not already exist. +label(OPTION_POSIXMQ_MSGSIZE)dit(bf(tt(posixmq-msgsize (mq-msgsize)))) + Sets the msgsize parameter of the POSIX message queue when creating it.nl() + Note: This option applies only when the queue does not already exist. enddit() @@ -3512,7 +3552,8 @@ label(TYPE_COMMAND_LINE)dit(command-line) A string specifying a program name and its arguments, separated by single spaces. label(TYPE_DATA)dit(data) - This is a more general data specification. The given text string contains + This is a more general data specification, "dalan" (low level data + description language). The given text string contains information about the target data type and value. Generally a leading character specifies the type of the following data item. In its specific context a default data type may exist.nl() @@ -3528,12 +3569,12 @@ label(TYPE_DATA)dit(data) dit(b) A signed byte (signed char).nl() dit(B) An unsigned byte (unsigned char).nl() dit(x) Following is an even number of hex digits, stored as sequence of - bytes.nl() + bytes, the data length is the resulting number of bytes.nl() Example: bf(x7f000001) (IP address 127.0.0.1) dit(") Following is a string that is used with the common conversions \n \r \t \f \b \a \e \0; the string must be closed with '"'. Please note that the quotes and backslashes need to be escaped from shell and socat() - conversion.nl() + conversion. No implicit \0 is appended.nl() Example: bf("Hello world!\n") dit(') A single char, with the usual conversions. Please note that the quotes and backslashes need to be escaped from shell and socat() conversion. @@ -3581,10 +3622,10 @@ label(TYPE_LONG)dit(long) label(TYPE_LONGLONG)dit(long long) A number read with code(strtoll()). The value must fit into a C long long. label(TYPE_OFF)dit(off_t) - An implementation dependend signed number, usually 32 bits, read with strtol + An implementation dependent signed number, usually 32 bits, read with strtol or strtoll. label(TYPE_OFF64)dit(off64_t) - An implementation dependend signed number, usually 64 bits, read with strtol + An implementation dependent signed number, usually 64 bits, read with strtol or strtoll. label(TYPE_MODE_T)dit(mode_t) An unsigned integer, read with code(strtoul()), specifying mode (permission) @@ -3972,7 +4013,7 @@ prompts. label(EXAMPLE_ADDRESS_PTY) label(EXAMPLE_OPTION_SYMBOLIC_LINK) label(EXAMPLE_OPTION_WAIT_SLAVE) -label(EXAMPLE_OPTION_NONBLOCK) +label(EXAMPLE_OPTION_O_NONBLOCK) mancommand(\.LP) mancommand(\.nf) mancommand(\fBsocat \\) @@ -4445,14 +4486,14 @@ both devices. Use pppd on device tt(/var/run/ppp) then. label(EXAMPLE_POSIXMQ_SEND) mancommand(\.LP) mancommand(\.nf) -mancommand(\fBsocat --experimental -u \\) +mancommand(\fBsocat -u \\) mancommand(\.RS) mancommand(\fBSTDIO \\ POSIXMQ-SEND:/queue1,unlink-early,mq-prio=10\fP) mancommand(\.RE) mancommand(\.fi) -htmlcommand(<hr><div class="shell">socat --experimental -u \ +htmlcommand(<hr><div class="shell">socat -u \ STDIO \ POSIXMQ-SEND:/queue1,unlink-early,mq-prio=10</div>) @@ -4464,7 +4505,7 @@ label(EXAMPLE_POSIXMQ_RECV_FORK) mancommand(\.LP) mancommand(\.nf) -mancommand(\fBsocat --experimental -u \\) +mancommand(\fBsocat -u \\) mancommand(\.RS) mancommand(\fBPOSIXMQ-RECV:/queue1,fork,max-children=3 \\ SYSTEM:"worker.sh"\fP) @@ -4472,7 +4513,7 @@ mancommand(\fBPOSIXMQ-RECV:/queue1,fork,max-children=3 \\ mancommand(\.RE) mancommand(\.fi) -htmlcommand(<hr><div class="shell">socat --experimental -u \ +htmlcommand(<hr><div class="shell">socat -u \ POSIXMQ-RECV:/queue1,fork,max-children=3 \ SYSTEM:"worker.sh"</div>) diff --git a/error.h b/error.h index 9853f8a..0cc4fac 100644 --- a/error.h +++ b/error.h @@ -183,7 +183,7 @@ #define Debug18(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18) #endif /* !(WITH_MSGLEVEL <= E_DEBUG) */ -/* message with software controlled serverity */ +/* message with software controlled severity */ #if WITH_MSGLEVEL <= E_FATAL #define Msg(l,m) msg(l,"%s",m) #define Msg1(l,m,a1) msg(l,m,a1) diff --git a/fdname.c b/fdname.c index e226bda..af7afc0 100644 --- a/fdname.c +++ b/fdname.c @@ -226,7 +226,7 @@ int sockname(int fd, FILE *outfile, char style) { #define FDNAME_OPTLEN 256 #define FDNAME_NAMELEN 256 socklen_t optlen; -#if HAVE_GETPROTOBYNUMBER || HAVE_GETPROTOBYNUMBER_R +#if (WITH_IP4 || WITH_IP6) && ( HAVE_GETPROTOBYNUMBER || HAVE_GETPROTOBYNUMBER_R ) struct protoent protoent, *protoentp; #endif #define PROTONAMEMAX 1024 @@ -278,7 +278,7 @@ int sockname(int fd, FILE *outfile, char style) { Getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &optacceptconn, &optlen); #endif -#if defined(SO_PROTOCOL) || defined(SO_PROTOTYPE) +#if (WITH_IP4 || WITH_IP6) && ( defined(SO_PROTOCOL) || defined(SO_PROTOTYPE) ) #if HAVE_GETPROTOBYNUMBER_R==1 /* Linux */ rc = getprotobynumber_r(proto, &protoent, protoname, sizeof(protoname), &protoentp); if (protoentp == NULL) { diff --git a/filan.c b/filan.c index 36def50..fb9229c 100644 --- a/filan.c +++ b/filan.c @@ -393,7 +393,7 @@ int filan_stat( break; #ifdef S_IFLNK case (S_IFLNK): /* 10, symbolic link */ - /* we wait for freadlink() sytem call */ + /* we wait for freadlink() system call */ break; #endif /* S_IFLNK */ break; @@ -804,13 +804,13 @@ int ipan(int fd, FILE *outfile) { } /* want to pass the fd to the next layer protocol. */ #if defined(SO_PROTOCOL) || defined(SO_PROTOTYPE) - if (Getsockopt(fd, SOL_SOCKET, + if ( #ifdef SO_PROTOCOL - SO_PROTOCOL, + Getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &optproto, &optlen) #elif defined(SO_PROTOTYPE) - SO_PROTOTYPE, + Getsockopt(fd, SOL_SOCKET, SO_PROTOTYPE, &optproto, &optlen) #endif - &optproto, &optlen) >= 0) { + >= 0) { switch (optproto) { #if WITH_TCP case IPPROTO_TCP: tcpan(fd, outfile); break; diff --git a/filan_main.c b/filan_main.c index 24dd5e9..d90432f 100644 --- a/filan_main.c +++ b/filan_main.c @@ -167,7 +167,7 @@ int main(int argc, const char *argv[]) { Nanosleep(&waittime, NULL); if (style == 0) { - /* this style gives detailled infos, but requires a file descriptor */ + /* This style gives detailed infos, but requires a file descriptor */ if (filename) { #if LATER /* this is just in case that S_ISSOCK does not work */ struct stat buf; diff --git a/hostan.c b/hostan.c index 80ea569..4258d3c 100644 --- a/hostan.c +++ b/hostan.c @@ -33,6 +33,11 @@ int hostan(FILE *outfile) { #endif fprintf(outfile, "sizeof(size_t) = %u\n", (unsigned int)sizeof(size_t)); + if ((char)-1 > 0) + fprintf(outfile, "typedef unsigned char char;\n"); + else + fprintf(outfile, "typedef signed char char;\n"); + # if HAVE_BASIC_SIZE_T==2 fprintf(outfile, "typedef unsigned short size_t; /* sizeof(size_t) = %u */\n", (unsigned int)sizeof(size_t)); #elif HAVE_BASIC_SIZE_T==4 diff --git a/procan-cdefs.c b/procan-cdefs.c index d9587f8..af56e69 100644 --- a/procan-cdefs.c +++ b/procan-cdefs.c @@ -15,30 +15,91 @@ #include "procan.h" int procan_cdefs(FILE *outfile) { - /* basic C/system constants */ + /* System constants */ +#ifdef __KERNEL__ + fprintf(outfile, "__KERNEL__ = \"%s\"\n", __KERNEL__); +#endif +#ifdef __GLIBC__ + fprintf(outfile, "__GLIBC__ = %d\n", __GLIBC__); +#endif + /* Basic C/system constants */ #ifdef FD_SETSIZE - fprintf(outfile, "#define FD_SETSIZE %u\n", FD_SETSIZE); + fprintf(outfile, "#define FD_SETSIZE %u\n", FD_SETSIZE); #endif #ifdef NFDBITS - fprintf(outfile, "#define NFDBITS %d\n", (int)NFDBITS); + fprintf(outfile, "#define NFDBITS %d\n", (int)NFDBITS); #endif #ifdef O_RDONLY - fprintf(outfile, "#define O_RDONLY %u\n", O_RDONLY); + fprintf(outfile, "#define O_RDONLY %u\n", O_RDONLY); #endif #ifdef O_WRONLY - fprintf(outfile, "#define O_WRONLY %u\n", O_WRONLY); + fprintf(outfile, "#define O_WRONLY %u\n", O_WRONLY); #endif #ifdef O_RDWR - fprintf(outfile, "#define O_RDWR %u\n", O_RDWR); + fprintf(outfile, "#define O_RDWR %u\n", O_RDWR); +#endif +#ifdef O_CREAT + fprintf(outfile, "#define O_CREAT 0x%06x /* 0%08o */\n", O_CREAT, O_CREAT); +#endif +#ifdef O_EXCL + fprintf(outfile, "#define O_EXCL 0x%06x /* 0%08o */\n", O_EXCL, O_EXCL); +#endif +#ifdef O_NOCTTY + fprintf(outfile, "#define O_NOCTTY 0x%06x /* 0%08o */\n", O_NOCTTY, O_NOCTTY); +#endif +#ifdef O_TRUNC + fprintf(outfile, "#define O_TRUNC 0x%06x /* 0%08o */\n", O_TRUNC, O_TRUNC); +#endif +#ifdef O_APPEND + fprintf(outfile, "#define O_APPEND 0x%06x /* 0%08o */\n", O_APPEND, O_APPEND); +#endif +#ifdef O_NONBLOCK + fprintf(outfile, "#define O_NONBLOCK 0x%06x /* 0%08o */\n", O_NONBLOCK, O_NONBLOCK); +#endif +#ifdef O_NDELAY + fprintf(outfile, "#define O_NDELAY 0x%06x /* 0%08o */\n", O_NDELAY, O_NDELAY); +#endif +#ifdef O_SYNC + fprintf(outfile, "#define O_SYNC 0x%06x /* 0%08o */\n", O_SYNC, O_SYNC); +#endif +#ifdef O_FSYNC + fprintf(outfile, "#define O_FSYNC 0x%06x /* 0%08o */\n", O_FSYNC, O_FSYNC); +#endif +#ifdef O_LARGEFILE + fprintf(outfile, "#define O_LARGEFILE 0x%06x /* 0%08o */\n", O_LARGEFILE, O_LARGEFILE); +#endif +#ifdef O_DIRECTORY + fprintf(outfile, "#define O_DIRECTORY 0x%06x /* 0%08o */\n", O_DIRECTORY, O_DIRECTORY); +#endif +#ifdef O_NOFOLLOW + fprintf(outfile, "#define O_NOFOLLOW 0x%06x /* 0%08o */\n", O_NOFOLLOW, O_NOFOLLOW); +#endif +#ifdef O_CLOEXEC + fprintf(outfile, "#define O_CLOEXEC 0x%06x /* 0%08o */\n", O_CLOEXEC, O_CLOEXEC); +#endif +#ifdef O_DIRECT + fprintf(outfile, "#define O_DIRECT 0x%06x /* 0%08o */\n", O_DIRECT, O_DIRECT); +#endif +#ifdef O_NOATIME + fprintf(outfile, "#define O_NOATIME 0x%06x /* 0%08o */\n", O_NOATIME, O_NOATIME); +#endif +#ifdef O_PATH + fprintf(outfile, "#define O_PATH 0x%06x /* 0%08o */\n", O_PATH, O_PATH); +#endif +#ifdef O_DSYNC + fprintf(outfile, "#define O_DSYNC 0x%06x /* 0%08o */\n", O_SYNC, O_SYNC); +#endif +#ifdef O_TMPFILE + fprintf(outfile, "#define O_TMPFILE 0x%06x /* 0%08o */\n", O_TMPFILE, O_TMPFILE); #endif #ifdef SHUT_RD - fprintf(outfile, "#define SHUT_RD %u\n", SHUT_RD); + fprintf(outfile, "#define SHUT_RD %u\n", SHUT_RD); #endif #ifdef SHUT_WR - fprintf(outfile, "#define SHUT_WR %u\n", SHUT_WR); + fprintf(outfile, "#define SHUT_WR %u\n", SHUT_WR); #endif #ifdef SHUT_RDWR - fprintf(outfile, "#define SHUT_RDWR %u\n", SHUT_RDWR); + fprintf(outfile, "#define SHUT_RDWR %u\n", SHUT_RDWR); #endif /* Compile time controls */ @@ -51,40 +112,40 @@ int procan_cdefs(FILE *outfile) { /* termios constants */ #ifdef CRDLY - fprintf(outfile, "#define CRDLY 0%011o\n", CRDLY); + fprintf(outfile, "#define CRDLY 0x%08x /* 0%011o */\n", CRDLY, CRDLY); #endif #ifdef CR0 - fprintf(outfile, "#define CR0 0%011o\n", CR0); + fprintf(outfile, "#define CR0 0x%08x /* 0%011o */\n", CR0, CR0); #endif #ifdef CR1 - fprintf(outfile, "#define CR1 0%011o\n", CR1); + fprintf(outfile, "#define CR1 0x%08x /* 0%011o */\n", CR1, CR1); #endif #ifdef CR2 - fprintf(outfile, "#define CR2 0%011o\n", CR2); + fprintf(outfile, "#define CR2 0x%08x /* 0%011o */\n", CR2, CR2); #endif #ifdef CR3 - fprintf(outfile, "#define CR3 0%011o\n", CR3); + fprintf(outfile, "#define CR3 0x%08x /* 0%011o */\n", CR3, CR3); #endif #ifdef TABDLY - fprintf(outfile, "#define TABDLY 0%011o\n", TABDLY); + fprintf(outfile, "#define TABDLY 0x%08x /* 0%011o */\n", TABDLY, TABDLY); #endif #ifdef TAB0 - fprintf(outfile, "#define TAB0 0%011o\n", TAB0); + fprintf(outfile, "#define TAB0 0x%08x /* 0%011o */\n", TAB0, TAB0); #endif #ifdef TAB1 - fprintf(outfile, "#define TAB1 0%011o\n", TAB1); + fprintf(outfile, "#define TAB1 0x%08x /* 0%011o */\n", TAB1, TAB1); #endif #ifdef TAB2 - fprintf(outfile, "#define TAB2 0%011o\n", TAB2); + fprintf(outfile, "#define TAB2 0x%08x /* 0%011o */\n", TAB2, TAB2); #endif #ifdef TAB3 - fprintf(outfile, "#define TAB3 0%011o\n", TAB3); + fprintf(outfile, "#define TAB3 0x%08x /* 0%011o */\n", TAB3, TAB3); #endif #ifdef CSIZE - fprintf(outfile, "#define CSIZE 0%011o\n", CSIZE); + fprintf(outfile, "#define CSIZE 0x%08x /* 0%011o */\n", CSIZE, CSIZE); #endif #ifdef TIOCEXCL - fprintf(outfile, "#define TIOCEXCL 0x%lx\n", (unsigned long)TIOCEXCL); + fprintf(outfile, "#define TIOCEXCL 0x%lx\n", (unsigned long)TIOCEXCL); #endif /* stdio constants */ @@ -188,5 +249,78 @@ int procan_cdefs(FILE *outfile) { #ifdef TCP_MAXSEG fprintf(outfile, "#define TCP_MAXSEG %d\n", TCP_MAXSEG); #endif +#ifdef AI_PASSIVE + fprintf(outfile, "#define AI_PASSIVE 0x%02x\n", AI_PASSIVE); +#endif +#ifdef AI_CANONNAME + fprintf(outfile, "#define AI_CANONNAME 0x%02x\n", AI_CANONNAME); +#endif +#ifdef AI_NUMERICHOST + fprintf(outfile, "#define AI_NUMERICHOST 0x%02x\n", AI_NUMERICHOST); +#endif +#ifdef AI_V4MAPPED + fprintf(outfile, "#define AI_V4MAPPED 0x%02x\n", AI_V4MAPPED); +#endif +#ifdef AI_ALL + fprintf(outfile, "#define AI_ALL 0x%02x\n", AI_ALL); +#endif +#ifdef AI_ADDRCONFIG + fprintf(outfile, "#define AI_ADDRCONFIG 0x%02x\n", AI_ADDRCONFIG); +#endif +#ifdef EAI_BADFLAGS + fprintf(outfile, "#define EAI_BADFLAGS %d\n", EAI_BADFLAGS); +#endif +#ifdef EAI_NONAME + fprintf(outfile, "#define EAI_NONAME %d\n", EAI_NONAME); +#endif +#ifdef EAI_AGAIN + fprintf(outfile, "#define EAI_AGAIN %d\n", EAI_AGAIN); +#endif +#ifdef EAI_FAIL + fprintf(outfile, "#define EAI_FAIL %d\n", EAI_FAIL); +#endif +#ifdef EAI_FAMILY + fprintf(outfile, "#define EAI_FAMILY %d\n", EAI_FAMILY); +#endif +#ifdef EAI_SOCKTYPE + fprintf(outfile, "#define EAI_SOCKTYPE %d\n", EAI_SOCKTYPE); +#endif +#ifdef EAI_SERVICE + fprintf(outfile, "#define EAI_SERVICE %d\n", EAI_SERVICE); +#endif +#ifdef EAI_MEMORY + fprintf(outfile, "#define EAI_MEMORY %d\n", EAI_MEMORY); +#endif +#ifdef EAI_SYSTEM + fprintf(outfile, "#define EAI_SYSTEM %d\n", EAI_SYSTEM); +#endif +#ifdef EAI_OVERFLOW + fprintf(outfile, "#define EAI_OVERFLOW %d\n", EAI_OVERFLOW); +#endif +#ifdef EAI_NODATA + fprintf(outfile, "#define EAI_NODATA %d\n", EAI_NODATA); +#endif +#ifdef EAI_ADDRFAMILY + fprintf(outfile, "#define EAI_ADDRFAMILY %d\n", EAI_ADDRFAMILY); +#endif +#ifdef EAI_INPROGRESS + fprintf(outfile, "#define EAI_INPROGRESS %d\n", EAI_INPROGRESS); +#endif +#ifdef EAI_CANCELED + fprintf(outfile, "#define EAI_CANCELED %d\n", EAI_CANCELED); +#endif +#ifdef EAI_NOTCANCELED + fprintf(outfile, "#define EAI_NOTCANCELED %d\n", EAI_NOTCANCELED); +#endif +#ifdef EAI_ALLDONE + fprintf(outfile, "#define EAI_ALLDONE %d\n", EAI_ALLDONE); +#endif +#ifdef EAI_INTR + fprintf(outfile, "#define EAI_INTR %d\n", EAI_INTR); +#endif +#ifdef EAI_IDN_ENCODE + fprintf(outfile, "#define EAI_IDN_ENCODE %d\n", EAI_IDN_ENCODE); +#endif + return 0; } diff --git a/procan.c b/procan.c index 22dd5e4..f51751c 100644 --- a/procan.c +++ b/procan.c @@ -187,10 +187,30 @@ int procan(FILE *outfile) { fprintf(outfile, "process group id if fg process / stderr = "F_pid"\n", Tcgetpgrp(2)); /* process owner, groups */ +#if HAVE_GETRESUID + { + uid_t ruid, euid, suid; + getresuid(&ruid, &euid, &suid); + fprintf(outfile, "user id = "F_uid"\n", ruid); + fprintf(outfile, "effective user id = "F_uid"\n", euid); + fprintf(outfile, "saved set-user id = "F_uid"\n", suid); + } +#else /* !HAVE_GETRESUID */ fprintf(outfile, "user id = "F_uid"\n", Getuid()); fprintf(outfile, "effective user id = "F_uid"\n", Geteuid()); +#endif /* !HAVE_GETRESUID */ +#if HAVE_GETRESGID + { + gid_t rgid, egid, sgid; + getresgid(&rgid, &egid, &sgid); + fprintf(outfile, "group id = "F_gid"\n", rgid); + fprintf(outfile, "effective group id = "F_gid"\n", egid); + fprintf(outfile, "saved set-group id = "F_gid"\n", sgid); + } +#else /* !HAVE_GETRESGID */ fprintf(outfile, "group id = "F_gid"\n", Getgid()); fprintf(outfile, "effective group id = "F_gid"\n", Getegid()); +#endif /* !HAVE_GETRESGID */ /* Simple process features */ fprintf(outfile, "\n"); diff --git a/procan_main.c b/procan_main.c index 7f70402..18b33de 100644 --- a/procan_main.c +++ b/procan_main.c @@ -13,6 +13,9 @@ const char copyright[] = "procan by Gerhard Rieger and contributors - send bug r #if HAVE_SYS_SELECT_H #include <sys/select.h> /* select(), fdset on FreeBSD */ #endif +#if HAVE_SYS_UTSNAME_H +#include <sys/utsname.h> /* uname(), struct utsname */ +#endif #include "mytypes.h" #include "error.h" #include "procan.h" @@ -22,6 +25,13 @@ const char copyright[] = "procan by Gerhard Rieger and contributors - send bug r #define WITH_HELP 1 static void procan_usage(FILE *fd); +static void procan_version(FILE *fd); + +const char copyright_procan[] = "procan by Gerhard Rieger and contributors - see www.dest-unreach.org"; +static const char procanversion[] = +#include "./VERSION" + ; +static const char timestamp[] = BUILD_DATE; int main(int argc, const char *argv[]) { @@ -39,8 +49,8 @@ int main(int argc, const char *argv[]) { case '?': case 'h': procan_usage(stdout); exit(0); #endif /* WITH_HELP */ case 'c': procan_cdefs(stdout); exit(0); -#if LATER case 'V': procan_version(stdout); exit(0); +#if LATER case 'l': diag_set(arg1[0][2], &arg1[0][3]); break; case 'd': diag_set('d', NULL); break; #endif @@ -80,9 +90,7 @@ static void procan_usage(FILE *fd) { fputs("Usage:\n", fd); fputs("procan [options]\n", fd); fputs(" options:\n", fd); -#if LATER fputs(" -V print version information to stdout, and exit\n", fd); -#endif #if WITH_HELP fputs(" -?|-h print a help text describing command line options\n", fd); #endif @@ -100,3 +108,17 @@ static void procan_usage(FILE *fd) { #endif } #endif /* WITH_HELP */ + + +void procan_version( + FILE *fd) +{ + struct utsname ubuf; + + fputs(copyright_procan, fd); fputc('\n', fd); + fprintf(fd, "procan version %s on %s\n", procanversion, timestamp); + uname(&ubuf); + fprintf(fd, " running on %s version %s, release %s, machine %s\n", + ubuf.sysname, ubuf.version, ubuf.release, ubuf.machine); + return; +} diff --git a/readline-test.sh b/readline-test.sh index 26f392f..569bde6 100755 --- a/readline-test.sh +++ b/readline-test.sh @@ -36,7 +36,7 @@ $ECHO if [ "$USERNAME" != "$CREDUSER" -o "$PASSWORD" != "$CREDPASS" ]; then $ECHO "Authentication failed" >&2 - exit -1 + exit 1 fi while $ECHO "$PROMPT\c"; read -r COMMAND; do diff --git a/readline.sh b/readline.sh index 1045303..2f08c04 100755 --- a/readline.sh +++ b/readline.sh @@ -4,15 +4,19 @@ # Published under the GNU General Public License V.2, see file COPYING # this is an attempt for a socat based readline wrapper -# usage: readline.sh <command> +# usage: readline.sh [options] <program> withhistfile=1 +STDERR= while true; do case "X$1" in - X-nh|X-nohist*) withhistfile=; shift; continue ;; - *) break;; + X-lf?*) STDERR="${1:3}" ;; + X-lf) shift; STDERR="$1" ;; + X-nh|X-nohist*) withhistfile= ;; + *) break;; esac + shift done PROGRAM="$@" @@ -25,12 +29,18 @@ fi # # -if test -w .; then +#if test -w .; then +if [ -z "$STDERR" ] && find . -maxdepth 0 -user $USER ! -perm /022 -print |grep ^ >/dev/null; then + # When cwd is owned by $USER and it is neither group nor world writable STDERR=./socat-readline.${1##*/}.log rm -f $STDERR -else + echo "$0: logs go to $STDERR" >&2 +elif [ -z "$STDERR" ]; then + echo "$0: insecure working directory, no logs are written" >&2 STDERR=/dev/null +else + echo "$0: logs go to $STDERR" >&2 fi -exec socat -d readline"$HISTOPT",noecho='[Pp]assword:' exec:"$PROGRAM",sigint,pty,setsid,ctty,raw,echo=0,stderr 2>$STDERR +exec socat -d READLINE"$HISTOPT",noecho='[Pp]assword:' EXEC:"$PROGRAM",sigint,pty,setsid,ctty,raw,echo=0,stderr 2>$STDERR diff --git a/socat-broker.sh b/socat-broker.sh index ccdea6f..b4b6dd2 100755 --- a/socat-broker.sh +++ b/socat-broker.sh @@ -37,6 +37,7 @@ while [ "$1" ]; do X-q) QUIET=1; OPTS="-d0" ;; X-d*|X-l?*) OPTS="$OPTS $1" ;; X-b|X-S|X-t|X-T|X-l) OPT=$1; shift; OPTS="$OPTS $OPT $1" ;; + X--experimental) ;; X-) break ;; X-*) echo "Unknown option \"$1\"" >&2 usage >&2 diff --git a/socat-chain.sh b/socat-chain.sh index fa8e93e..357aff0 100755 --- a/socat-chain.sh +++ b/socat-chain.sh @@ -77,6 +77,7 @@ while [ "$1" ]; do X-q) QUIET=1; OPTS="-d0" ;; X-d*|X-l?*) OPTS="$OPTS $1" ;; X-b|X-S|X-t|X-T|X-l) OPT=$1; shift; OPTS="$OPTS $OPT $1" ;; + X--experimental) ;; X-) break ;; X-*) echo "$0: Unknown option \"$1\"" >&2 usage >&2 diff --git a/socat-mux.sh b/socat-mux.sh index 084c0e6..204cd89 100755 --- a/socat-mux.sh +++ b/socat-mux.sh @@ -2,7 +2,7 @@ # Copyright Gerhard Rieger and contributors (see file CHANGES) # Published under the GNU General Public License V.2, see file COPYING -# Shell script to build a many-to-one, one-to-all communication +# Shell script to establish many-to-one, one-to-all communications. # It starts two Socat instances that communicate via IPv4 broadcast, # the first of which forks a child process for each connected client. @@ -43,6 +43,7 @@ while [ "$1" ]; do X-q) QUIET=1; OPTS="-d0" ;; X-d*|X-l?*) OPTS="$OPTS $1" ;; X-b|X-S|X-t|X-T|X-l) OPT=$1; shift; OPTS="$OPTS $OPT $1" ;; + X--experimental) ;; X-) break ;; X-*) echo "$0: Unknown option \"$1\"" >&2 usage >&2 diff --git a/socat.c b/socat.c index cf1685d..3e9cc91 100644 --- a/socat.c +++ b/socat.c @@ -282,6 +282,8 @@ int main(int argc, const char *argv[]) { socat_opts.total_timeout.tv_usec = (rto-socat_opts.total_timeout.tv_sec) * 1000000; } + xioparms.total_timeout.tv_sec = socat_opts.total_timeout.tv_sec; + xioparms.total_timeout.tv_usec = socat_opts.total_timeout.tv_usec; break; case 'u': if (arg1[0][2]) { socat_opt_hint(stderr, arg1[0][1], arg1[0][2]); Exit(1); } socat_opts.lefttoright = true; break; @@ -783,7 +785,7 @@ int socat(const char *address1, const char *address2) { int i; for (i = 0; i < NUMUNKNOWN; ++i) { if (XIO_RDSTREAM(sock1)->para.exec.pid == diedunknown[i]) { - /* child has alread died... but it might have put regular data into + /* Child has already died... but it might have put regular data into the communication channel, so continue */ Info2("child "F_pid" has already died with status %d", XIO_RDSTREAM(sock1)->para.exec.pid, statunknown[i]); @@ -826,7 +828,7 @@ int socat(const char *address1, const char *address2) { int i; for (i = 0; i < NUMUNKNOWN; ++i) { if (XIO_RDSTREAM(sock2)->para.exec.pid == diedunknown[i]) { - /* child has alread died... but it might have put regular data into + /* Child has already died... but it might have put regular data into the communication channel, so continue */ Info2("child "F_pid" has already died with status %d", XIO_RDSTREAM(sock2)->para.exec.pid, statunknown[i]); @@ -863,11 +865,12 @@ int childleftdata(xiofile_t *xfd) { XIO_RDSTREAM(xfd)->para.exec.pid == 0) { struct timeval timeout = { 0, 0 }; - if (XIO_READABLE(xfd) && !(XIO_RDSTREAM(xfd)->eof >= 2 && !XIO_RDSTREAM(xfd)->ignoreeof)) { - in.fd = XIO_GETRDFD(xfd); - in.events = POLLIN/*|POLLRDBAND*/; - in.revents = 0; - } + if (XIO_RDSTREAM(xfd)->eof >= 2 && !XIO_RDSTREAM(xfd)->ignoreeof) + return 0; + + in.fd = XIO_GETRDFD(xfd); + in.events = POLLIN/*|POLLRDBAND*/; + in.revents = 0; do { int _errno; retval = xiopoll(&in, 1, &timeout); @@ -875,7 +878,7 @@ int childleftdata(xiofile_t *xfd) { } while (retval < 0 && errno == EINTR); if (retval < 0) { - Error5("xiopoll({%d,%0o}, 1, {"F_tv_sec"."F_tv_usec"}): %s", + Error5("xiopoll({%d,0%o}, 1, {"F_tv_sec"."F_tv_usec"}): %s", in.fd, in.events, timeout.tv_sec, timeout.tv_usec, strerror(errno)); return -1; @@ -1013,7 +1016,7 @@ int _socat(void) { /* for ignoreeof */ if (polling) { if (!wasaction) { - if (socat_opts.total_timeout.tv_usec <= 1000000) { + if (socat_opts.total_timeout.tv_usec < 1000000) { if (total_timeout.tv_usec < socat_opts.pollintv.tv_usec) { total_timeout.tv_usec += 1000000; total_timeout.tv_sec -= 1; @@ -1131,7 +1134,7 @@ int _socat(void) { */ if (retval < 0) { - Error11("xiopoll({%d,%0o}{%d,%0o}{%d,%0o}{%d,%0o}, 4, {"F_tv_sec"."F_tv_usec"}): %s", + Error11("xiopoll({%d,0%o}{%d,0%o}{%d,0%o}{%d,0%o}, 4, {"F_tv_sec"."F_tv_usec"}): %s", fds[0].fd, fds[0].events, fds[1].fd, fds[1].events, fds[2].fd, fds[2].events, fds[3].fd, fds[3].events, timeout.tv_sec, timeout.tv_usec, strerror(errno)); @@ -1336,7 +1339,6 @@ int _socat(void) { should be at least MAXTIMESTAMPLEN bytes long. returns 0 on success or -1 if an error occurred */ int gettimestamp(char *timestamp) { - size_t bytes; #if HAVE_CLOCK_GETTIME struct timespec now; #elif HAVE_PROTOTYPE_LIB_gettimeofday @@ -1364,17 +1366,16 @@ int gettimestamp(char *timestamp) { } #endif #if HAVE_STRFTIME - bytes = strftime(timestamp, 20, "%Y/%m/%d %H:%M:%S", localtime(&nowt)); + strftime(timestamp, 20, "%Y/%m/%d %H:%M:%S", localtime(&nowt)); #if HAVE_CLOCK_GETTIME - bytes += sprintf(timestamp+19, "."F_tv_nsec" ", now.tv_nsec/1000); + sprintf(timestamp+19, "."F_tv_nsec" ", now.tv_nsec/1000); #elif HAVE_PROTOTYPE_LIB_gettimeofday - bytes += sprintf(timestamp+19, "."F_tv_usec" ", now.tv_usec); + sprintf(timestamp+19, "."F_tv_usec" ", now.tv_usec); #else strncpy(×tamp[bytes++], " ", 2); #endif #else strcpy(timestamp, ctime(&nowt)); - bytes = strlen(timestamp); #endif return 0; } diff --git a/socat.spec b/socat.spec index 3d2b7a1..55e1d70 100644 --- a/socat.spec +++ b/socat.spec @@ -1,6 +1,6 @@ %define majorver 1.8 -%define minorver 0.2 +%define minorver 0.3 Summary: socat - multipurpose relay Name: socat diff --git a/socks4a-echo.sh b/socks4a-echo.sh index 7360366..91d255a 100755 --- a/socks4a-echo.sh +++ b/socks4a-echo.sh @@ -37,7 +37,7 @@ esac if [ $(echo "x\c") = "x" ]; then E="" elif [ $(echo -e "x\c") = "x" ]; then E="-e" else - echo "cannot suppress trailing newline on echo" >&2 + echo "$0: cannot suppress trailing newline on echo" >&2 exit 1 fi ECHO="echo $E" @@ -58,7 +58,7 @@ else fi if [ "$vn" != $($ECHO "\04") ]; then $ECHO "$SOCKSREPLY_FAILED" - echo "invalid socks version requested" >&2 + echo "$0 invalid socks version requested" >&2 exit fi @@ -69,7 +69,7 @@ else fi if [ "$cd" != $($ECHO "\01") ]; then $ECHO "$SOCKSREPLY_FAILED" - echo "invalid socks operation requested" >&2 + echo "$0: invalid socks operation requested" >&2 exit fi @@ -82,7 +82,7 @@ a=$(dd bs=1 count=6 2>/dev/null) if [ "$a" != "$($ECHO "}m\0\0\0\01")" ]; then sleep 1 $ECHO "$SOCKSREPLY_FAILED" - echo "wrong socks address or port requested" >&2 + echo "$0: wrong socks address or port requested" >&2 exit fi @@ -93,7 +93,7 @@ else fi if [ "$u" != "nobody" ]; then $ECHO "$SOCKSREPLY_FAILED" - echo "wrong socks user requested" >&2 + echo "$0: wrong socks user requested" >&2 exit fi @@ -104,7 +104,7 @@ else fi if [ "$h" != "localhost" ]; then $ECHO "$SOCKSREPLY_FAILED" - echo "wrong socks address requested" >&2 + echo "$0: wrong socks address requested" >&2 exit fi diff --git a/socks4echo.sh b/socks4echo.sh index 48ea536..44c631a 100755 --- a/socks4echo.sh +++ b/socks4echo.sh @@ -9,6 +9,7 @@ # it is required for test.sh # for TCP, use this script as: # socat tcp-l:1080,reuseaddr,crlf system:"socks4echo.sh" +# Then connect with a socks4 request for 32.98.76.54:32109 and user nobody # older bash and ksh do not have -n option to read command; we try dd then #if echo a |read -n 1 null >/dev/null 2>&1; then @@ -36,7 +37,7 @@ esac if [ $(echo "x\c") = "x" ]; then E="" elif [ $(echo -e "x\c") = "x" ]; then E="-e" else - echo "cannot suppress trailing newline on echo" >&2 + echo "$0: cannot suppress trailing newline on echo" >&2 exit 1 fi ECHO="echo $E" @@ -57,7 +58,7 @@ else fi if [ "$vn" != $($ECHO "\04") ]; then $ECHO "$SOCKSREPLY_FAILED" - echo "invalid socks version requested" >&2 + echo "$0: invalid socks version requested" >&2 exit fi @@ -68,7 +69,7 @@ else fi if [ "$cd" != $($ECHO "\01") ]; then $ECHO "$SOCKSREPLY_FAILED" - echo "invalid socks operation requested" >&2 + echo "$0: invalid socks operation requested" >&2 exit fi @@ -91,7 +92,7 @@ else fi if [ "$u" != "nobody" ]; then $ECHO "$SOCKSREPLY_FAILED" - echo "wrong socks user requested (expected \"nobody\")" >&2 + echo "$0: wrong socks user requested (expected \"nobody\")" >&2 exit fi diff --git a/socks5server-echo.sh b/socks5server-echo.sh new file mode 100755 index 0000000..04e562a --- /dev/null +++ b/socks5server-echo.sh @@ -0,0 +1,67 @@ +#! /usr/bin/env bash +# Source: socks5connect-echo.sh + +# Copyright Gerhard Rieger and contributors (see file CHANGES) +# Published under the GNU General Public License V.2, see file COPYING + +# Performs primitive simulation of a socks5 server with echo function via stdio. +# Accepts and answers SOCKS5 CONNECT request without authentication to +# 8.8.8.8:80, however is does not connect there but just echoes data. +# It is required for test.sh +# For TCP, use this script as: +# socat TCP-L:1080,reuseaddr EXEC:"socks5connect-echo.sh" + +#set -vx + +if [ "$SOCAT" ]; then + : +elif type socat >/dev/null 2>&1; then + SOCAT=socat +else + SOCAT=./socat +fi + +case `uname` in +HP-UX|OSF1) + CAT="$SOCAT -u STDIN STDOUT" + ;; +*) + CAT=cat + ;; +esac + +A="7f000001" +P="0050" + +# Read and parse SOCKS5 greeting +read _ v b c _ <<<"$($SOCAT -u -,readbytes=3 - |od -t x1)" +#echo "$v $b $c" >&2 +if [ "$v" != 05 ]; then echo "$0: Packet1: expected version x05, got \"$v\"" >&2; exit 1; fi +if [ "$b" != 01 ]; then echo "$0: Packet1: expected 01 auth methods, got \"$b\"" >&2; exit 1; fi +if [ "$c" != 00 ]; then echo "$0: Packet1: expected auth method 00, got \"$c\"" >&2; exit 1; fi +# Send answer +echo -en "\x05\x00" + +# Read and parse SOCKS5 connect request +read _ v b c d a1 a2 a3 a4 p1 p2 _ <<<"$($SOCAT -u -,readbytes=10 - |od -t x1)" +#echo "$v $b $c $d $a1 $a2 $a3 $a4 $p1 $p2" >&2 +a="$a1$a2$a3$a4" +p="$p1$p2" +if [ "$v" != 05 ]; then echo "$0: Packet2: expected version x05, got \"$v\"" >&2; exit 1; fi +if [ "$b" != 01 ] && [ "$b" != 02 ]; then echo "$0: Packet2: expected connect request 01 or bind request 02, got \"$b\"" >&2; exit 1; fi +if [ "$c" != 00 ]; then echo "$0: Packet2: expected reserved 00, got \"$c\"" >&2; exit 1; fi +if [ "$d" != 01 ]; then echo "$0: Packet2: expected address type 01, got \"$d\"" >&2; exit 1; fi +if [ "$a" != "$A" ]; then echo "$0: Packet2: expected address $A, got \"$a\"" >&2; exit 1; fi +if [ "$p" != "$P" ]; then echo "$0: Packet2: expected port $P, got \"$p\"" >&2; exit 1; fi +if [ "$z" != "" ]; then echo "$0: Packet2: trailing data \"$z\"" >&2; exit 1; fi +# Send answer +echo -en "\x05\x00\x00\x01\x10\x00\x1f\x64\x1f\x64" + +# Bind/listen/passive mode +if [ "$b" == 02 ]; then + sleep 1 # pretend to be waiting for connection + echo -en "\x05\x00\x00\x01\x10\xff\x1f\x64\x23\x28" +fi + +# perform echo function +$CAT diff --git a/sslcls.c b/sslcls.c index 4e29d71..700b2a3 100644 --- a/sslcls.c +++ b/sslcls.c @@ -368,6 +368,7 @@ int sycSSL_connect(SSL *ssl) { int result; Debug1("SSL_connect(%p)", ssl); result = SSL_connect(ssl); + if (!diag_in_handler) diag_flush(); Debug1("SSL_connect() -> %d", result); return result; } diff --git a/sycls.c b/sycls.c index 900cee3..3eb0058 100644 --- a/sycls.c +++ b/sycls.c @@ -1421,11 +1421,11 @@ unsigned int Sleep(unsigned int seconds) { #if HAVE_NANOSLEEP unsigned int Nanosleep(const struct timespec *req, struct timespec *rem) { int retval, _errno; - Debug3("nanosleep({"F_time",%ld},%p)", req->tv_sec, req->tv_nsec, rem); + Debug3("nanosleep({"F_time".%09ld}, %p)", req->tv_sec, req->tv_nsec, rem); retval = nanosleep(req, rem); _errno = errno; if (rem) { - Debug3("nanosleep(,{"F_time",%ld}) -> %d", + Debug3("nanosleep(,{"F_time".%09ld}) -> %d", rem->tv_sec, rem->tv_nsec, retval); } else { Debug1("nanosleep() -> %d", retval); @@ -1513,6 +1513,9 @@ void *Malloc(size_t size) { Error1("malloc("F_Zd"): out of memory", size); return NULL; } +#if WITH_DEVTESTS + memset(result, 0x55, size); +#endif /* WITH_DEVTESTS */ return result; } @@ -1540,6 +1543,18 @@ void *Realloc(void *ptr, size_t size) { return result; } +/* Like Realloc(), but gets info about old size for overwrite test */ +void *Realloc3(void *ptr, size_t size, size_t oldsize) { + void *result = Realloc(ptr, size); + if (result == NULL) + return result; +#if WITH_DEVTESTS + if (size > oldsize) + memset(result+oldsize, 0x55, size-oldsize); +#endif /* WITH_DEVTESTS */ + return result; +} + #if _WITH_TERMIOS int Tcgetattr(int fd, struct termios *termios_p) { int i, result, _errno; diff --git a/sycls.h b/sycls.h index 8f8ded5..fe9bb70 100644 --- a/sycls.h +++ b/sycls.h @@ -148,6 +148,7 @@ struct hostent *Getipnodebyname(const char *name, int af, int flags, void *Malloc(size_t size); void *Calloc(size_t nmemb, size_t size); void *Realloc(void *ptr, size_t size); +void *Realloc3(void *ptr, size_t size, size_t oldsize); int Tcgetattr(int fd, struct termios *termios_p); int Tcsetattr(int fd, int optional_actions, struct termios *termios_p); char *Ttyname(int fd); @@ -257,6 +258,7 @@ void Add_history(const char *string); #define Malloc(s) malloc(s) #define Calloc(n,s) calloc(n,s) #define Realloc(p,s) realloc(p,s) +#define Realloc3(p,s,o) realloc(p,s) #define Tcgetattr(f,t) tcgetattr(f,t) #define Tcsetattr(f,o,t) tcsetattr(f,o,t) #define Ttyname(f) ttyname(f) diff --git a/sysincludes.h b/sysincludes.h index f51e368..a8e60be 100644 --- a/sysincludes.h +++ b/sysincludes.h @@ -150,6 +150,9 @@ #if HAVE_LINUX_IF_TUN_H #include <linux/if_tun.h> #endif +#if HAVE_NETINET_DCCP_H +#include <netinet/dccp.h> +#endif #if HAVE_LINUX_DCCP_H #include <linux/dccp.h> #endif @@ -182,7 +185,7 @@ #if WITH_NAMESPACES && HAVE_SCHED_H #include <sched.h> #endif -#if WITH_POSIXMQ +#if WITH_POSIXMQ && HAVE_MQUEUE_H #include <mqueue.h> /* POSIX MQ */ #endif #if WITH_READLINE diff --git a/sysutils.c b/sysutils.c index ee24454..f25531a 100644 --- a/sysutils.c +++ b/sysutils.c @@ -27,9 +27,22 @@ const int one = 1; Returns <0 on unhandled error, errno valid Will only return <0 or bytes */ -ssize_t writefull(int fd, const void *buff, size_t bytes) { +/* Assuming your pipe size is 65536 - find out with: + filan -i 1 |grep F_GETPIPE_SZ |sed 's|.*\(F_GETPIPE_SZ=[1-9][0-9]*\).*|\1|' + Then we can test partial write with something like: + socat -d4 -lu -b 262144 -u /dev/zero,readbytes=262144 -,o-nonblock |{ sleep 3; wc -c; } +*/ +ssize_t writefull( + int fd, + const void *buff, + size_t bytes, + const struct timeval *tmo0) { size_t writt = 0; ssize_t chk; + struct pollfd pfd; + struct timeval tmo = { 0 }; + int rc; + while (1) { chk = Write(fd, (const char *)buff + writt, bytes - writt); if (chk < 0) { @@ -40,15 +53,34 @@ ssize_t writefull(int fd, const void *buff, size_t bytes) { case EWOULDBLOCK: #endif Warn4("write(%d, %p, "F_Zu"): %s", fd, (const char *)buff+writt, bytes-writt, strerror(errno)); - Sleep(1); continue; - default: return -1; + pfd.fd = fd; + pfd.events = POLLOUT; + pfd.revents = 0; + if (tmo0 != NULL) { + tmo.tv_sec = tmo0->tv_sec; + tmo.tv_usec = tmo0->tv_usec; + } + rc = xiopoll(&pfd, 1, (tmo.tv_sec!=0 || tmo.tv_usec!=0) ? &tmo : NULL); + if (rc == 0) { + Notice("inactivity timeout triggered"); + errno = ETIMEDOUT; + return -1; + } + continue; + default: + return -1; } + } else if (chk == bytes) { + /* First attempt, complete write */ + return chk; } else if (writt+chk < bytes) { - Warn4("write(%d, %p, "F_Zu"): only wrote "F_Zu" bytes, trying to continue (rev.direction is blocked)", + Warn4("write(%d, %p, "F_Zu"): only wrote "F_Zu" bytes, trying to continue (meanwhile, other direction is blocked)", fd, (const char *)buff+writt, bytes-writt, chk); writt += chk; - } else { - writt = bytes; + } else if (writt == 0) { + /* First attempt, write complete - no extra message */ + return chk; + } else { /* write completed */ break; } } @@ -548,7 +580,7 @@ int getusergroups(const char *user, gid_t *list, int *ngroups) { /* we prefer getgrouplist because it may be much faster with many groups, but it is not standard */ gid_t grp, twogrps[2]; int two = 2; - /* getgrouplist requires to pass an extra group id, typically the users primary group, that is then added to the supplementary group list. We don't want such an additional group in the result, but there is not "unspecified" gid value available. Thus we try to find an abitrary supplementary group id that we then pass in a second call to getgrouplist. */ + /* getgrouplist requires to pass an extra group id, typically the users primary group, that is then added to the supplementary group list. We don't want such an additional group in the result, but there is not "unspecified" gid value available. Thus we try to find an arbitrary supplementary group id that we then pass in a second call to getgrouplist. */ grp = 0; Getgrouplist(user, grp, twogrps, &two); if (two == 1) { @@ -677,7 +709,7 @@ int xiopoll(struct pollfd fds[], unsigned long nfds, struct timeval *timeout) { } -#if WITH_TCP || WITH_UDP +#if WITH_TCP || WITH_UDP || WITH_SCTP || WITH_DCCP || WITH_UDPLITE /* returns port in network byte order; ipproto==IPPROTO_UDP resolves as UDP service, every other value resolves as TCP */ @@ -702,10 +734,10 @@ int parseport(const char *portname, int ipproto) { return se->s_port; } -#endif /* WITH_TCP || WITH_UDP */ +#endif /* WITH_TCP || WITH_UDP || WITH_SCTP || WITH_DCCP || WITH_UDPLITE */ -#if WITH_IP4 || WITH_IP6 || WITH_INTERFACE +#if WITH_IP4 || WITH_IP6 || _WITH_INTERFACE /* check the systems interfaces for ifname and return its index or -1 if no interface with this name was found The system calls require an arbitrary socket; the calling program may @@ -729,8 +761,8 @@ int ifindexbyname(const char *ifname, int anysock) { } if (anysock >= 0) { s = anysock; - } else if ((s = Socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { - Error1("socket(PF_INET, SOCK_DGRAM, IPPROTO_IP): %s", strerror(errno)); + } else if ((s = Socket(PF_INET, SOCK_DGRAM, 0)) < 0) { + Error1("socket(PF_INET, SOCK_DGRAM, 0): %s", strerror(errno)); return -1; } @@ -756,10 +788,10 @@ int ifindexbyname(const char *ifname, int anysock) { return -1; #endif /* !defined(HAVE_ STRUCT_IFREQ) && defined(SIOCGIFCONF) && defined(SIOCGIFINDEX) */ } -#endif /* WITH_IP4 || WITH_IP6 || WITH_INTERFACE */ +#endif /* WITH_IP4 || WITH_IP6 || _WITH_INTERFACE */ -#if WITH_IP4 || WITH_IP6 || WITH_INTERFACE +#if WITH_IP4 || WITH_IP6 || _WITH_INTERFACE /* like ifindexbyname(), but also allows the index number as input - in this case it does not lookup the index. writes the resulting index to *ifindex and returns 0, @@ -783,7 +815,7 @@ int ifindex(const char *ifname, unsigned int *ifindex, int anysock) { *ifindex = val; return 0; } -#endif /* WITH_IP4 || WITH_IP6 || WITH_INTERFACE */ +#endif /* WITH_IP4 || WITH_IP6 || _WITH_INTERFACE */ int _xiosetenv(const char *envname, const char *value, int overwrite, const char *sep) { diff --git a/sysutils.h b/sysutils.h index 5e8ae10..cfdff04 100644 --- a/sysutils.h +++ b/sysutils.h @@ -47,7 +47,7 @@ struct xiorange { extern const int one; #endif -extern ssize_t writefull(int fd, const void *buff, size_t bytes); +extern ssize_t writefull(int fd, const void *buff, size_t bytes, const struct timeval *tmo0); #if _WITH_SOCKET extern socklen_t socket_init(int af, union sockaddr_union *sa); diff --git a/test.sh b/test.sh index 5204ac7..62df2e8 100755 --- a/test.sh +++ b/test.sh @@ -39,7 +39,7 @@ usage() { $ECHO "Usage: $0 <options> [<test-spec> ...]" $ECHO "options:" $ECHO "\t-h \t\tShow this help" - $ECHO "\t-t <sec> \tBase for timeouts in seconds, default: 0.1" + $ECHO "\t-t <sec> \tBase for timeouts in seconds, default is automatically determined" $ECHO "\t-v \t\tBe more verbose, show failed commands" $ECHO "\t-n <num> \tOnly perform test with given number" $ECHO "\t-N <num> \tOnly perform tests starting with given number" @@ -48,6 +48,7 @@ usage() { $ECHO "\t-d \t\tShow log output of commands, even when they did not fail (not yet completed)" $ECHO "\t-D \t\tOutput some platform/system specific defines (variables)" $ECHO "\t--internet \tAllow tests that send packets to Internet" + $ECHO "\t--experimental \tApply --experimental option to Socat" $ECHO "\t--expect-fail N1,N2,... \tIgnore failure of these tests" $ECHO "\ttest-spec \Number of test or name of test" $ECHO "Contents of environment variable OPTS are passed to Socat invocations, e.'g:" @@ -65,6 +66,7 @@ VERBOSE= DEBUG= DEFS= INTERNET= +EXPERIMENTAL= OPT_EXPECT_FAIL= EXPECT_FAIL= while [ "$1" ]; do case "X$1" in @@ -78,8 +80,9 @@ while [ "$1" ]; do X-n) shift; NUMCOND="test \$N -eq $1" ;; X-N?*) NUMCOND="test \$N -gt ${1#-N}" ;; X-N) shift; NUMCOND="test \$N -ge $1" ;; - X-C) rm -f testcert*.conf testcert.dh testcli*.* testsrv*.* ;; + X-C) rm -f testcert*.conf testcert.dh testcli*.* testsrv*.* testalt.* ;; X--internet|X-internet) INTERNET=1 ;; # allow access to 3rd party Internet hosts + X--experimental) EXPERIMENTAL=1 ;; X--expect-fail|X-expect-fail) OPT_EXPECT_FAIL=1; shift; EXPECT_FAIL="$1" ;; X-*) echo "Unknown option \"$1\"" >&2 usage >&2 @@ -90,9 +93,12 @@ while [ "$1" ]; do done debug=$DEBUG +# Applying patch 1.8.0.3 to 1.8.0.2 generates this non executably +[ -f ./socks5server-echo.sh ] && chmod a+x ./socks5server-echo.sh + [ "$DEFS" ] && echo "BASH_VERSION=\"$BASH_VERSION\"" >&2 -[ "$DEFS" ] && echo "ECHO_E=\"$ECHO_E\"" >&2 +[ "$DEFS" ] && echo "ECHO=\"$ECHO\"" >&2 UNAME=`uname` [ "$DEFS" ] && echo "UNAME=\"$UNAME\"" >&2 @@ -109,6 +115,24 @@ MICROS=${S}${uS} MICROS=${MICROS##0000}; MICROS=${MICROS##00}; MICROS=${MICROS##0} # changed below again +divide_uint_by_1000000 () { + x=$1 + if [ ${#x} -ge 7 ]; then + echo ${x%??????}.${x: -6}; + else + y=000000$x; + f=${y: -6}; + echo 0.$f; + fi +} + + +# output the value in seconds for n * val_t +relsecs () { + local n="$1" + divide_uint_by_1000000 $((n*MICROS)) +} + _MICROS=$((MICROS+999999)); SECONDs="${_MICROS%??????}" [ -z "$SECONDs" ] && SECONDs=0 [ "$DEFS" ] && echo "SECONDs=\"$SECONDs\"" >&2 @@ -129,21 +153,22 @@ if [ -z "$PROCAN" ]; then if test -x ./procan; then PROCAN="./procan"; elif type if [ -z "$FILAN" ]; then if test -x ./filan; then FILAN="./filan"; elif ! type filan >/dev/null 2>&1; then FILAN=filan; elif test -x ${SOCAT%/*}/filan; then FILAN=${SOCAT%/*}/filan; else FILAN=false; fi; fi [ "$DEFS" ] && echo "FILAN=\"$FILAN\"" >&2 +if ! sleep 0.1 2>/dev/null; then + sleep () { + $SOCAT -T "$1" PIPE PIPE + } +fi + if [ -z "$val_t" ]; then - # Determine the time Socat needs for an empty run + # Estimate the time Socat needs for an empty run + sleep 0.5 # immediately after build the first runs are extremely fast $SOCAT /dev/null /dev/null # populate caches - MILLIs=$(bash -c 'time socat /dev/null /dev/null' 2>&1 |grep ^real |sed 's/.*m\(.*\)s.*/\1/' |tr -d ,.) + MILLIs=$(bash -c "time for _ in {1..3}; do $SOCAT -d0 $opts /dev/null /dev/null; done" 2>&1 |grep ^real |sed 's/.*m\(.*\)s.*/\1/' |tr -d ,.) while [ "${MILLIs:0:1}" = '0' ]; do MILLIs=${MILLIs##0}; done # strip leading '0' to avoid octal [ -z "$MILLIs" ] && MILLIs=1 - [ "$DEFS" ] && echo "MILLIs=\"$MILLIs\" (1)" >&2 - - # On my idle development computer this value flaps from 0.001 to 0.004 - # 0.001 lets many tests fail, so we triple the result - MILLIs=$((3*MILLIs)) - [ "$DEFS" ] && echo "MILLIs=\"$MILLIs\" (2)" >&2 + [ "$DEFS" ] && echo "MILLIs=\"$MILLIs\"" >&2 MICROS=${MILLIs}000 - #set -vx case $MICROS in ???????*) val_t=${MICROS%??????}.${MICROS: -6} ;; *) x=000000$MICROS; val_t=0.${x: -6} ;; @@ -183,7 +208,7 @@ PATH=$PATH:/sbin # RHEL6:ip case "$0" in */*) PATH="${0%/*}:$PATH" esac -PATH=.:$PATH # for usleep,relsleep +PATH=.:$PATH # for relsleep [ "$DEFS" ] && echo "PATH=\"$PATH\"" >&2 #OPENSSL_RAND="-rand /dev/egd-pool" @@ -191,6 +216,13 @@ PATH=.:$PATH # for usleep,relsleep MISCDELAY=1 OPTS="$opt_t $OPTS" + +if [ "$EXPERIMENTAL" ]; then + if $SOCAT -h |grep -e --experimental >/dev/null; then + OPTS="$OPTS --experimental" + fi +fi + opts="$OPTS" [ "$DEFS" ] && echo "opts=\"$opts\"" >&2 @@ -230,12 +262,12 @@ fi # for some tests we need a network interface if type ip >/dev/null 2>&1; then - INTERFACE=$(ip r get 8.8.8.8 |grep ' dev ' |head -n 1 |sed "s/.*dev[[:space:]][[:space:]]*\([^[:space:]][^[:space:]]*\).*/\1/") + INTERFACE=$(ip r get 9.9.9.9 |grep ' dev ' |head -n 1 |sed "s/.*dev[[:space:]][[:space:]]*\([^[:space:]][^[:space:]]*\).*/\1/") else case "$UNAME" in Linux) if [ "$IP" ]; then - INTERFACE="$($IP route get 8.8.8.8 |grep ' dev ' |sed -e 's/.* dev //' -e 's/ .*//')" + INTERFACE="$($IP route get 9.9.9.9 |grep ' dev ' |sed -e 's/.* dev //' -e 's/ .*//')" else INTERFACE="$(netstat -rn |grep -e "^default" -e "^0\.0\.0\.0" |awk '{print($8);}')" fi ;; @@ -267,7 +299,7 @@ FOPEN_MAX=$($PROCAN -c 2>/dev/null |grep '^#define[ ][ ]*FOPEN_MAX' |awk '{print [ "$DEFS" ] && echo "FOPEN_MAX=\"$FOPEN_MAX\"" >&2 PF_INET6="$($PROCAN -c |grep "^#define[[:space:]]*PF_INET6[[:space:]]" |cut -d' ' -f3)" [ "$DEFS" ] && echo "PF_INET6=\"$PF_INET6\"" >&2 -TIOCEXCL="$($PROCAN -c |grep "^#define[[:space:]]*TIOCEXCL[[:space:]]" |cut -d' ' -f3)" +TIOCEXCL="$($PROCAN -c |grep "^#define[[:space:]]*TIOCEXCL[[:space:]]" |{ read _ _ v; echo "$v"; })" [ "$DEFS" ] && echo "TIOCEXCL=\"$TIOCEXCL\"" >&2 SOL_SOCKET="$($PROCAN -c |grep "^#define[[:space:]]*SOL_SOCKET[[:space:]]" |cut -d' ' -f3)" [ "$DEFS" ] && echo "SOL_SOCKET=\"$SOL_SOCKET\"" >&2 @@ -280,89 +312,6 @@ SIZE_T=$($PROCAN |grep "^[^[:space:]]*size_t" |awk '{print($3);}') #AI_ADDRCONFIG=; if [ "$($SOCAT -hhh |grep ai-addrconfig)" ]; then AI_ADDRCONFIG="ai-addrconfig=0"; fi #[ "$DEFS" ] && echo "AI_ADDRCONFIG=\"$AI_ADDRCONFIG\"" >&2 -# SSL certificate contents -TESTCERT_CONF=testcert.conf -TESTCERT6_CONF=testcert6.conf -TESTALT_CONF=testalt.conf -# -TESTCERT_COMMONNAME="$LOCALHOST" -TESTCERT_COMMONNAME6="$LOCALHOST6" -TESTCERT_COUNTRYNAME="XY" -TESTCERT_LOCALITYNAME="Lunar Base" -TESTCERT_ORGANIZATIONALUNITNAME="socat" -TESTCERT_ORGANIZATIONNAME="dest-unreach" -TESTCERT_SUBJECT="C = $TESTCERT_COUNTRYNAME, CN = $TESTCERT_COMMONNAME, O = $TESTCERT_ORGANIZATIONNAME, OU = $TESTCERT_ORGANIZATIONALUNITNAME, L = $TESTCERT_LOCALITYNAME" -TESTCERT_ISSUER="C = $TESTCERT_COUNTRYNAME, CN = $TESTCERT_COMMONNAME, O = $TESTCERT_ORGANIZATIONNAME, OU = $TESTCERT_ORGANIZATIONALUNITNAME, L = $TESTCERT_LOCALITYNAME" -RSABITS=2048 # Ubuntu-20.04 with OpenSSL-1.1.1f does not work with 1024 nor 1536 -DSABITS=2048 -cat >$TESTCERT_CONF <<EOF -prompt=no - -[ req ] -default_bits = $RSABITS -distinguished_name=Test - -[ Test ] -countryName=$TESTCERT_COUNTRYNAME -commonName=$TESTCERT_COMMONNAME -O=$TESTCERT_ORGANIZATIONNAME -OU=$TESTCERT_ORGANIZATIONALUNITNAME -L=$TESTCERT_LOCALITYNAME - -EOF - -cat >$TESTCERT6_CONF <<EOF -prompt=no - -[ req ] -default_bits = $RESBITS -distinguished_name=Test - -[ Test ] -countryName=$TESTCERT_COUNTRYNAME -commonName=$TESTCERT_COMMONNAME6 -O=$TESTCERT_ORGANIZATIONNAME -OU=$TESTCERT_ORGANIZATIONALUNITNAME -L=$TESTCERT_LOCALITYNAME - -EOF - -cat >$TESTALT_CONF <<EOF -# config for generation of self signed certificate with IP addresses in -# SubjectAltNames -prompt=no - -[ req ] -default_bits = $RSABITS -distinguished_name = subject -x509_extensions = x509_ext - -[ subject ] -countryName=$TESTCERT_COUNTRYNAME -commonName=servername -O=$TESTCERT_ORGANIZATIONNAME -OU=$TESTCERT_ORGANIZATIONALUNITNAME -L=$TESTCERT_LOCALITYNAME - -[ x509_ext ] -subjectAltName = @alternate_names - -[ alternate_names ] -DNS.1 = localhost -DNS.2 = localhost4 -DNS.3 = localhost6 -IP.1 = 127.0.0.1 -IP.2 = ::1 - -EOF - -# clean up from previous runs -rm -f testcli.{crt,key,pem} -rm -f testsrv.{crt,key,pem} -rm -f testcli6.{crt,key,pem} -rm -f testsrv6.{crt,key,pem} -rm -f testalt.{crt,key,pem} - CAT="cat" OD_C="od -c" @@ -380,47 +329,6 @@ tolower () { esac } -if ! which usleep >/dev/null 2>&1; then -cat >usleep <<EOF -#! /usr/bin/env bash -# temporary script from Socat test.sh: -# sleep for a number of µs -u=\$1 -l=\${#u} -i=0 -[ "\$l" -gt 6 ] && i=\${u%??????} -u0=000000\$u -s=\${i}.\${u0: -6:6}; -#echo \$s -sleep \$s -EOF -chmod a+x usleep -fi - -# precision sleep; takes seconds with fractional part; sleep does this on all test platforms -if false; then -psleep () { - local T="$1" - [ "$T" = 0 ] && T=0.000002 - #$SOCAT -T "$T" PIPE PIPE 2>/dev/null - sleep "$T" -} -# time in microseconds to wait in some situations -if ! type usleep >/dev/null 2>&1 || - usleep 0 2>&1 |grep -q deprecated; then - usleep () { - local n="$1" - case "$n" in - *???????) S="${n%??????}"; uS="${n:${#n}-6}" ;; - *) S=0; uS="00000$n"; uS="${uS:${#uS}-6}" ;; - esac - #$SOCAT -T "$S.$uS" PIPE PIPE 2>/dev/null - sleep "$S.$uS" - } -fi -#USLEEP=usleep -fi - # calculate the time i*MICROS, output as float number for us with -t reltime () { local n="$1" @@ -433,11 +341,12 @@ reltime () { echo "$S.$uS" } -# A sleep with configurable clocking ($vat_t) +# A sleep with configurable clocking ($val_t) # val_t should be at least the time that a Socat invocation, no action, and # termination takes relsleep () { - usleep $(($1*MICROS)) + #sleep $(($1*MICROS/1000000)) + sleep $(divide_uint_by_1000000 $(($1*MICROS)) ) } cat >relsleep <<-'EOF' @@ -543,7 +452,7 @@ fi # need output like "644" case "$UNAME" in - Linux) fileperms() { stat -L --print "%a\n" "$1" 2>/dev/null; } ;; + #Linux) fileperms() { stat -L --print "%a\n" "$1" 2>/dev/null; } ;; FreeBSD) fileperms() { stat -L -x "$1" |grep ' Mode:' |sed 's/.* Mode:[[:space:]]*([0-9]\([0-7][0-7][0-7]\).*/\1/'; } ;; *) fileperms() { local p s=0 c @@ -583,7 +492,7 @@ if2bc4() { case "$UNAME" in Linux) if [ "$IP" ]; then - BROADCASTIF=$($IP r get 8.8.8.8 |grep ' dev ' |sed 's/.*\<dev[[:space:]][[:space:]]*\([a-z0-9][a-z0-9]*\).*/\1/') + BROADCASTIF=$($IP r get 9.9.9.9 |grep ' dev ' |sed 's/.*\<dev[[:space:]][[:space:]]*\([a-z0-9][a-z0-9]*\).*/\1/') else BROADCASTIF=$(route -n |grep '^0.0.0.0 ' |awk '{print($8);}') fi @@ -657,20 +566,12 @@ vt100|vt320|linux|xterm|cons25|dtterm|aixterm|sun-color|xterm-color|xterm-256col RED="\0033[31m" GREEN="\0033[32m" YELLOW="\0033[33m" -# if [ "$UNAME" = SunOS ]; then -# NORMAL="\0033[30m" -# else - NORMAL="\0033[39m" -# fi - else + NORMAL="\0033[39m" + else # "\101" RED="\033[31m" GREEN="\033[32m" YELLOW="\033[33m" -# if [ "$UNAME" = SunOS ]; then -# NORMAL="\033[30m" -# else - NORMAL="\033[39m" -# fi + NORMAL="\033[39m" fi OK="${GREEN}OK${NORMAL}" FAILED="${RED}FAILED${NORMAL}" @@ -689,42 +590,6 @@ if [ -x /usr/xpg4/bin/id ]; then PATH="/usr/xpg4/bin:$PATH" fi -OPENSSL_S_CLIENT_4= -OPENSSL_S_CLIENT_DTLS= -init_openssl_s_client () { - if openssl s_client -help 2>&1 |grep -q ' -4 '; then - OPENSSL_S_CLIENT_4="-4" - else - OPENSSL_S_CLIENT_4=" " - fi - if openssl s_client -help 2>&1 | grep -q ' -dtls '; then - OPENSSL_S_CLIENT_DTLS=-dtls - else - OPENSSL_S_CLIENT_DTLS=-dtls1 - fi -} - -OPENSSL_S_SERVER_4= -OPENSSL_S_SERVER_DTLS= -OPENSSL_S_SERVER_NO_IGN_EOF= -init_openssl_s_server () { - if openssl s_server -help 2>&1 |grep -q ' -4 '; then - OPENSSL_S_SERVER_4="-4" - else - OPENSSL_S_SERVER_4=" " - fi - if openssl s_server -help 2>&1 | grep -q ' -dtls '; then - OPENSSL_S_SERVER_DTLS="-dtls" - else - OPENSSL_S_SERVER_DTLS="-dtls1" - fi - if openssl s_server -help 2>&1 | grep -q ' -no-ign_eof '; then - OPENSSL_S_SERVER_NO_IGN_EOF="-no-ign_eof" - else - OPENSSL_S_SERVER_NO_IGN_EOF=" " - fi -} - [ -z "$TESTS" ] && TESTS="consistency functions filan" # use '%' as separation char @@ -744,6 +609,8 @@ mkdir -p "$TD" echo "Using temp directory $TD" +RESULTS="$TD/results.txt" # file for list of results + case "$TESTS" in *%consistency%*) # test if addresses are sorted alphabetically: @@ -752,7 +619,7 @@ TF="$TD/socat-q" IFS="$($ECHO ' \n\t')" if ! $SOCAT -hhh >/dev/null; then echo "Failed: $SOCAT -hhh" >&2 - exit -1 + exit 2 fi $SOCAT -hhh |sed -n '/^ address-head:/,/^ opts:/ p' |grep -v -e "^ address-head:" -e "^ opts:" |sed -e 's/^[[:space:]]*//' -e 's/[: ].*//' |grep -v '^<' >"$TF" $SOCAT -hhh |sed -n '/^ address-head:/,/^ opts:/ p' |grep -v -e "^ address-head:" -e "^ opts:" |sed -e 's/^[[:space:]]*//' -e 's/[: ].*//' |grep -v '^<' |LC_ALL=C sort |diff "$TF" - >"$TF-diff" @@ -785,6 +652,63 @@ fi /bin/rm "$TF-diff" esac +case "$TESTS" in +*%consistency%*) + # Test if help shows option types without inconsistency + $ECHO "testing if help shows option types correctly...\c" + TF="$TD/socat-hhh" + LINE="$($SOCAT -hhh |grep "^[[:space:]]*ip-add-source-membership\>")" + if [ -z "$LINE" ]; then + $ECHO $CANT + else + TYPE="$($ECHO "$LINE" |sed 's/^.*type=\([^[:space:]][^[:space:]]*\).*/\1/')" + if [ "$TYPE" != "IP-MREQ-SOURCE" ]; then + $ECHO "\n*** help does not show option types correctly" >&2 + exit 1 + else + echo " ok" + fi + fi +esac + +case "$TESTS" in +*%consistency%*) + # Test if help shows option phases without inconsistency + $ECHO "testing if help shows option phases correctly...\c" + TF="$TD/socat-hhh" + LINE="$($SOCAT -hhh |grep "^[[:space:]]*dash\>")" + if [ -z "$LINE" ]; then + $ECHO $CANT + else + PHASE="$($ECHO "$LINE" |sed 's/^.*phase=\([^[:space:]][^[:space:]]*\).*/\1/')" + if [ "$PHASE" != "PREEXEC" ]; then + $ECHO "\n*** help does not show option phases correctly" >&2 + exit 1 + else + echo " ok" + fi + fi +esac + +case "$TESTS" in +*%consistency%*) + # Test if help shows option groups without inconsistency + $ECHO "testing if help shows option groups correctly...\c" + TF="$TD/socat-hhh" + LINE="$($SOCAT -hhh |grep "^[[:space:]]*udplite-recv-cscov\>")" + if [ -z "$LINE" ]; then + $ECHO $CANT + else + GROUP="$($ECHO "$LINE" |sed 's/^.*groups=\([^[:space:]][^[:space:]]*\).*/\1/')" + if [ "$GROUP" != "UDPLITE" ]; then + $ECHO "\n*** help does not show option groups correctly" >&2 + exit 1 + else + echo " ok" + fi + fi +esac + #============================================================================== N=1 @@ -794,18 +718,41 @@ numCANT=0 listOK= listFAIL= listCANT= -namesFAIL= + +ok () { + numOK=$((numOK+1)) + listOK="$listOK $N" + do_result OK +} + +cant () { + numCANT=$((numCANT+1)) + listCANT="$listCANT $N" + do_result CANT +} + +failed () { + numFAIL=$((numFAIL+1)) + listFAIL="$listFAIL $N" + do_result FAILED +} + +do_result () { + #echo "RESULTS=\"$RESULTS\"" >&2; exit + echo "$N $NAME $1" >>$RESULTS +} #============================================================================== # test if selected socat features work ("FUNCTIONS") testecho () { local N="$1" - local title="$2" - local arg1="$3"; [ -z "$arg1" ] && arg1="-" - local arg2="$4"; [ -z "$arg2" ] && arg2="echo" - local opts="$5" - local T="$6"; [ -z "$T" ] && T=0 # fractional seconds + local NAME="$2" + local title="$3" + local arg1="$4"; [ -z "$arg1" ] && arg1="-" + local arg2="$5"; [ -z "$arg2" ] && arg2="echo" + local opts="$6" + local T="$7"; [ -z "$T" ] && T=0 # fractional seconds local tf="$td/test$N.stdout" local te="$td/test$N.stderr" local tdiff="$td/test$N.diff" @@ -817,7 +764,7 @@ testecho () { #echo "$da" |$cmd >"$tf" 2>"$te" { sleep $T; echo "$da"; sleep $T; } | { $TRACE $SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te"; echo $? >"$td/test$N.rc"; } & pid1=$! - #sleep 5 && kill $rc1 2>/dev/null & + #sleep 5 && kill $pid1 2>/dev/null & # rc2=$! wait $pid1 # kill $rc2 2>/dev/null @@ -825,22 +772,19 @@ testecho () { $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$TRACE $SOCAT $opts $arg1 $arg2" >&2 cat "$te" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif echo "$da" |diff - "$tf" >"$tdiff" 2>&1; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$SOCAT $opts $arg1 $arg2" >&2; fi if [ -n "$debug" ]; then cat $te >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED:\n" echo "$TRACE $SOCAT $opts $arg1 $arg2" >&2 cat "$te" >&2 echo diff: >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND } @@ -849,11 +793,12 @@ testecho () { # flush of od buffers testod () { local num="$1" - local title="$2" - local arg1="$3"; [ -z "$arg1" ] && arg1="-" - local arg2="$4"; [ -z "$arg2" ] && arg2="echo" - local opts="$5" - local T="$6"; [ -z "$T" ] && T=0 # fractional seconds + local NAME="$2" + local title="$3" + local arg1="$4"; [ -z "$arg1" ] && arg1="-" + local arg2="$5"; [ -z "$arg2" ] && arg2="echo" + local opts="$6" + local T="$7"; [ -z "$T" ] && T=0 # fractional seconds local tf="$td/test$N.stdout" local te="$td/test$N.stderr" local tr="$td/test$N.ref" @@ -868,25 +813,36 @@ testod () { $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$TRACE $SOCAT $opts $arg1 $arg2" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $num" + failed # elif echo "$daout" |diff - "$tf" >"$tdiff" 2>&1; then elif diff "$tr" "$tf" >"$tdiff" 2>&1; then $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED: diff:\n" echo "$TRACE $SOCAT $opts $arg1 $arg2" cat "$te" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $num" + failed fi fi # NUMCOND } +# bash before version 3 aborts scripts that contain unquoted '=~' +# Therefore we create a shell script and quotedly fill it with '=~' for newer +# bashes [regexp regular expressions] +mkdir -p $td/bin +rm -f $td/bin/re_match +if [ "${BASH_VERSION%%[.]*}" -le 2 ]; then + echo '[ -n "$(echo "$1" |sed -n "/$2/ p")" ]' >$td/bin/re_match +else + echo '[[ "$1" =~ $2 ]]' >$td/bin/re_match +fi +chmod a+x $td/bin/re_match +PATH=$PATH:$td/bin + + # test if the socat executable has these features compiled in # print the first missing address type testfeats () { @@ -904,7 +860,8 @@ testfeats () { fi fi if SOCAT_MAIN_WAIT= $SOCAT -V |grep "#define WITH_$A 1\$" >/dev/null; then - if [[ "$A" =~ OPENSSL.* ]]; then +# if [[ "$A" =~ OPENSSL.* ]]; then + if re_match "$A" "OPENSSL.*"; then gentestcert testsrv gentestcert testcli fi @@ -955,6 +912,10 @@ testoptions () { # if not: prints ev.message to stderr, returns 1 childprocess () { local l + case "$1" in + [1-9]*) ;; + *) echo "childprocess \"$1\": not a number" >&2; exit 2 ;; + esac case "$UNAME" in AIX) l="$(ps -fade |grep "^........ ...... $(printf %6u $1)")" ;; FreeBSD) l="$(ps -faje |grep "^........ ..... $(printf %5u $1)")" ;; @@ -978,6 +939,10 @@ childprocess () { childpids () { local recursive i if [ "X$1" = "X-r" ]; then recursive=1; shift; fi + case "$1" in + [1-9]*) ;; + *) echo "childpids \"$1\": not a number" >&2; exit 2 ;; + esac case "$UNAME" in AIX) l="$(ps -fade |grep "^........ ...... $(printf %6u $1)" |awk '{print($2);}')" ;; FreeBSD) l="$(ps -fl |grep "^[^ ][^ ]*[ ][ ]*[0-9][0-9]*[ ][ ]*$1[ ]" |awk '{print($2);}')" ;; @@ -1053,7 +1018,7 @@ runsip4 () { CYGWIN*) l=$(ipconfig |grep IPv4);; *) l=$($IFCONFIG -a |grep ' ::1[^:0-9A-Fa-f]') ;; esac - [ -z "$l" ] && return 1 + [ -z "$l" ] && return 1 # existence of interface might not suffice, check for routeability: case "$UNAME" in Darwin) ping -c 1 127.0.0.1 >/dev/null 2>&1; l="$?" ;; @@ -1076,9 +1041,9 @@ runsip6 () { AIX) l=$($IFCONFIG lo0 |grep 'inet6 ::1[/%]') ;; HP-UX) l=$($IFCONFIG lo0 |grep ' inet6 ') ;; Linux) if [ "$IP" ]; then - l=$($IP address |$GREP_E 'inet6 ::1/128') + l="$($IP address |$GREP_E 'inet6 ::1/128')" else - l=$($IFCONFIG |$GREP_E 'inet6 (addr: )?::1/?') + l="$($IFCONFIG |$GREP_E 'inet6 (addr: )?::1/?')" fi ;; NetBSD)l=$($IFCONFIG -a |grep 'inet6 ::1\>');; OSF1) l=$($IFCONFIG -a |grep ' inet6 ') ;; @@ -1087,7 +1052,7 @@ runsip6 () { CYGWIN*) l=$(ipconfig |grep IPv6);; *) l=$($IFCONFIG -a |grep ' ::1[^:0-9A-Fa-f]') ;; esac - [ -z "$l" ] && return 1 + [ -z "$l" ] && return 1 # existence of interface might not suffice, check for routeability: case "$UNAME" in Darwin) $PING6 -c 1 ::1 >/dev/null 2>&1; l="$?" ;; @@ -1183,11 +1148,146 @@ runsunix () { routesip6 () { runsip6 >/dev/null || { echo route6; return 1; } - ping -c 1 -s 0 -6 2606:4700:4700::1111 >/dev/null 2>&1 || { echo route6; return 1; } + $PING6 -c 1 2606:4700:4700::1111 >/dev/null 2>&1 || { echo route6; return 1; } return 0; } +# SSL needs runsip6(), thus moved down + +# SSL certificate contents +TESTCERT_CONF=testcert.conf +TESTCERT6_CONF=testcert6.conf +TESTALT_CONF=testalt.conf +# +TESTCERT_COMMONNAME="$LOCALHOST" +TESTCERT_COMMONNAME6="$LOCALHOST6" +TESTCERT_COUNTRYNAME="XY" +TESTCERT_LOCALITYNAME="Lunar Base" +TESTCERT_ORGANIZATIONALUNITNAME="socat" +TESTCERT_ORGANIZATIONNAME="dest-unreach" +TESTCERT_SUBJECT="C = $TESTCERT_COUNTRYNAME, CN = $TESTCERT_COMMONNAME, O = $TESTCERT_ORGANIZATIONNAME, OU = $TESTCERT_ORGANIZATIONALUNITNAME, L = $TESTCERT_LOCALITYNAME" +TESTCERT_ISSUER="C = $TESTCERT_COUNTRYNAME, CN = $TESTCERT_COMMONNAME, O = $TESTCERT_ORGANIZATIONNAME, OU = $TESTCERT_ORGANIZATIONALUNITNAME, L = $TESTCERT_LOCALITYNAME" +RSABITS=2048 # Ubuntu-20.04 with OpenSSL-1.1.1f does not work with 1024 nor 1536 +DSABITS=2048 +cat >$TESTCERT_CONF <<EOF +prompt=no + +[ req ] +default_bits = $RSABITS +distinguished_name=Test + +[ Test ] +countryName=$TESTCERT_COUNTRYNAME +commonName=$TESTCERT_COMMONNAME +O=$TESTCERT_ORGANIZATIONNAME +OU=$TESTCERT_ORGANIZATIONALUNITNAME +L=$TESTCERT_LOCALITYNAME + +EOF + +cat >$TESTCERT6_CONF <<EOF +prompt=no + +[ req ] +default_bits = $RESBITS +distinguished_name=Test + +[ Test ] +countryName=$TESTCERT_COUNTRYNAME +commonName=$TESTCERT_COMMONNAME6 +O=$TESTCERT_ORGANIZATIONNAME +OU=$TESTCERT_ORGANIZATIONALUNITNAME +L=$TESTCERT_LOCALITYNAME + +EOF + +cat >$TESTALT_CONF <<EOF +# config for generation of self signed certificate with IP addresses in +# SubjectAltNames +prompt=no + +[ req ] +default_bits = $RSABITS +distinguished_name = subject +x509_extensions = x509_ext + +[ subject ] +countryName=$TESTCERT_COUNTRYNAME +commonName=servername +O=$TESTCERT_ORGANIZATIONNAME +OU=$TESTCERT_ORGANIZATIONALUNITNAME +L=$TESTCERT_LOCALITYNAME + +[ x509_ext ] +subjectAltName = @alternate_names + +[ alternate_names ] +DNS.1 = localhost +DNS.2 = localhost4 +DNS.3 = localhost6 +IP.1 = 127.0.0.1 +EOF + +if runsip6; then + cat >>$TESTALT_CONF <<EOF +IP.2 = ::1 +EOF +fi + + +# clean up from previous runs +rm -f testcli.{crt,key,pem} +rm -f testsrv.{crt,key,pem} +rm -f testcli6.{crt,key,pem} +rm -f testsrv6.{crt,key,pem} +rm -f testalt.{crt,key,pem} + +OPENSSL_S_CLIENT_4= +OPENSSL_S_CLIENT_DTLS= +init_openssl_s_client () { + if openssl s_client -help 2>&1 |grep -q ' -4 '; then + OPENSSL_S_CLIENT_4="-4" + else + OPENSSL_S_CLIENT_4=" " + fi + if openssl s_client -help 2>&1 | grep -q ' -dtls1_2 '; then + OPENSSL_S_CLIENT_DTLS="-dtls1_2" + elif openssl s_client -help 2>&1 | grep -q ' -dtls1 '; then + OPENSSL_S_CLIENT_DTLS="-dtls1" + elif openssl s_client -help 2>&1 | grep -q ' -dtls '; then + OPENSSL_S_CLIENT_DTLS="-dtls" + else + OPENSSL_S_CLIENT_DTLS= + fi +} + +OPENSSL_S_SERVER_4= +OPENSSL_S_SERVER_DTLS= +OPENSSL_S_SERVER_NO_IGN_EOF= +init_openssl_s_server () { + if openssl s_server -help 2>&1 |grep -q ' -4 '; then + OPENSSL_S_SERVER_4="-4" + else + OPENSSL_S_SERVER_4=" " + fi + if openssl s_server -help 2>&1 | grep -q ' -dtls1_2 '; then + OPENSSL_S_SERVER_DTLS="-dtls1_2" + elif openssl s_server -help 2>&1 | grep -q ' -dtls1 '; then + OPENSSL_S_SERVER_DTLS="-dtls1" + elif openssl s_server -help 2>&1 | grep -q ' -dtls '; then + OPENSSL_S_SERVER_DTLS="-dtls" + else + OPENSSL_S_SERVER_DTLS= + fi + if openssl s_server -help 2>&1 | grep -q ' -no-ign_eof '; then + OPENSSL_S_SERVER_NO_IGN_EOF="-no-ign_eof" + else + OPENSSL_S_SERVER_NO_IGN_EOF=" " + fi +} + + # Perform a couple of checks to make sure the test has a chance of a useful # result: # platform is supported, features compiled in, addresses and options @@ -1215,13 +1315,6 @@ checkconds() { [ "$i" ] && { echo "Only on (one of) $unames"; return 255; } fi - if [ "$root" = "root" ]; then - if [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then - echo "Must be root" - return 255 - fi - fi - if [ "$progs" ]; then for i in $progs; do if ! type >/dev/null 2>&1; then @@ -1262,11 +1355,20 @@ checkconds() { fi if [ "$inet" ]; then - if [ -z "$NTERNET" ]; then + if [ -z "$INTERNET" ]; then echo "Use test.sh option --internet" return 255 fi fi + + # Only at the end, so we get a better overview of missing features + if [ "$root" = "root" ]; then + if [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then + echo "Must be root" + return 255 + fi + fi + return 0 } @@ -1298,7 +1400,7 @@ waitip4proto () { # SunOS) l=$(netstat -an -f inet -P raw |grep '.*[1-9*]\.'$proto' [ ]*Idle') ;; # HP-UX) l=$(netstat -an |grep '^raw 0 0 .*[0-9*]\.'$proto' .* \*\.\* ') ;; # OSF1) l=$(/usr/sbin/netstat -an |grep '^raw 0 0 .*[0-9*]\.'$proto' [ ]*\*\.\*') ;; - *) #l=$(netstat -an |grep -i 'raw .*[0-9*][:.]'$proto' ') ;; + *) #l=$(netstat -an |grep -i 'raw .*[0-9*][:.]'$proto' ') ;; relsleep 5; return 0 ;; esac [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ @@ -1391,6 +1493,24 @@ checktcpport () { return 1 } +waittcpport () { + local port="$1" + local logic="$2" # 0..wait until free; 1..wait until listening (default) + local timeout="$3" + while true; do +#echo "timeout=\"$timeout\"" >&2 + if [ "$logic" = 0 ]; then + if checktcpport $1; then break; fi + else + if ! checktcpport $1; then break; fi + fi + if [ $timeout -le 0 ]; then return 1; fi + sleep 1 + let --timeout; + done + return 0; +} + checktcp4port () { checktcpport $1 } @@ -1423,7 +1543,7 @@ waittcp4port () { OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;; CYGWIN*) l=$(netstat -an -p TCP |grep '^ TCP [0-9.]*:'$port' .* LISTENING') ;; DragonFly) l=$(netstat -ant |grep '^tcp4 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;; - *) l=$(netstat -an |grep -i 'tcp .*[0-9*][:.]'$port' .* listen') ;; + *) l=$(netstat -an |grep -i 'tcp .*[0-9*][:.]'$port' .* listen') ;; esac if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ \( \( $logic -eq 0 \) -a -z "$l" \) ]; then @@ -1504,7 +1624,7 @@ waitudp4port () { HP-UX) l=$(netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' .* \*\.\* ') ;; OSF1) l=$(/usr/sbin/netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\*') ;; DragonFly) l=$(netstat -an |grep '^udp4 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;; - *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;; + *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;; esac if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ \( \( $logic -eq 0 \) -a -z "$l" \) ]; then @@ -1565,7 +1685,7 @@ waitsctp4port () { while [ $timeout -gt 0 ]; do case "$UNAME" in Linux) if [ "$SS" ]; then - l=$($SS -4 -n 2>/dev/null |grep "^sctp.*LISTEN .*:$port\>") + l=$($SS -4 -a -n 2>/dev/null |grep "^sctp.*LISTEN .*:$port\>") else l=$(netstat -n -a |grep '^sctp .*[0-9*]:'$port' .* LISTEN') fi ;; @@ -1580,7 +1700,7 @@ waitsctp4port () { # HP-UX) l=$(netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' .* LISTEN$') ;; # OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;; # CYGWIN*) l=$(netstat -an -p TCP |grep '^ TCP [0-9.]*:'$port' .* LISTENING') ;; - *) l=$(netstat -an |grep -i 'sctp .*[0-9*][:.]'$port' .* listen') ;; + *) l=$(netstat -an |grep -i 'sctp .*[0-9*][:.]'$port' .* listen') ;; esac if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ \( \( $logic -eq 0 \) -a -z "$l" \) ]; then @@ -1610,6 +1730,7 @@ waitudplite4port () { Linux) #if [ "$SS" ]; then #l=$($SS -4 -l -n -u |grep "^UNCONN .*:$port\>") #else + # On Ubuntu-20 only netstat shows udplite ports if ! netstat -nU >/dev/null 2>&1; then return 0 # speculative fi @@ -1644,6 +1765,51 @@ waitudplite4port () { return 1 } +# wait until an DCCP4 listen port is ready +waitdccp4port () { + local port="$1" + local logic="$2" # 0..wait until free; 1..wait until listening + local timeout="$3" + local l + local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here + [ "$logic" ] || logic=1 + [ "$timeout" ] || timeout=5 + while [ $timeout -gt 0 ]; do + case "$UNAME" in + Linux) + # On Ubuntu-20, only ss shows DCCP ports + if [ "$SS" ]; then + l=$($SS -4 -a -n 2>/dev/null |grep "^dccp.*LISTEN .*:$port\>") + else + l=$(netstat -n -a |grep '^dccp .*[0-9*]:'$port' .* LISTEN') + fi ;; +# FreeBSD) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; +# NetBSD) l=$(netstat -an |grep '^tcp .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;; +# Darwin) case "$(uname -r)" in +# [1-5]*) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; +# *) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; +# esac ;; +# AIX) l=$(netstat -an |grep '^tcp[^6] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; + SunOS) l=$(netstat -an -f inet -P dccp |grep '.*[1-9*]\.'$port' .*\* 0 .* LISTEN') ;; +# HP-UX) l=$(netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' .* LISTEN$') ;; +# OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;; +# CYGWIN*) l=$(netstat -an -p TCP |grep '^ TCP [0-9.]*:'$port' .* LISTENING') ;; + *) l=$(netstat -an |grep -i 'dccp .*[0-9*][:.]'$port' .* listen') ;; + esac + if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ + \( \( $logic -eq 0 \) -a -z "$l" \) ]; then + set ${vx}vx + return 0 + fi + sleep $val_t + timeout=$((timeout-1)) + done + + $ECHO "!port $port timed out! \c" >&2 + set ${vx}vx + return 1 +} + # check if a TCP6 port is in use # exits with 0 when it is not used checktcp6port () { @@ -1675,7 +1841,7 @@ waittcp6port () { SunOS) l=$(netstat -an -f inet6 -P tcp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;; #OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;; DragonFly) l=$(netstat -ant |grep '^tcp6 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;; - *) l=$(netstat -an |grep -i 'tcp6 .*:'$port' .* listen') ;; + *) l=$(netstat -an |grep -i 'tcp6 .*:'$port' .* listen') ;; esac if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ \( \( $logic -eq 0 \) -a -z "$l" \) ]; then @@ -1718,14 +1884,14 @@ waitudp6port () { fi ;; FreeBSD) l=$(netstat -an |$GREP_E '^udp(6|46) .*[0-9*]\.'$port' .* \*\.\*') ;; NetBSD) l=$(netstat -an |grep '^udp6 .* \*\.'$port' [ ]* \*\.\*') ;; - OpenBSD) l=$(netstat -an |grep '^udp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; + OpenBSD) l=$(netstat -an |grep '^udp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; Darwin) l=$(netstat -an |$GREP_E '^udp4?6 +[0-9]+ +[0-9]+ +[0-9a-z:%*]+\.'$port' +[0-9a-z:%*.]+') ;; AIX) l=$(netstat -an |grep '^udp[6 ] 0 0 .*[*0-9]\.'$port' .* \*\.\*[ ]*$') ;; SunOS) l=$(netstat -an -f inet6 -P udp |grep '.*[1-9*]\.'$port' [ ]*Idle') ;; #HP-UX) l=$(netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' ') ;; #OSF1) l=$(/usr/sbin/netstat -an |grep '^udp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\*') ;; DragonFly) l=$(netstat -ant |grep '^udp6 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;; - *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;; + *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;; esac if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ \( \( $logic -eq 0 \) -a -z "$l" \) ]; then @@ -1760,9 +1926,9 @@ waitsctp6port () { while [ $timeout -gt 0 ]; do case "$UNAME" in Linux) if [ "$SS" ]; then - l=$($SS -6 -n 2>/dev/null |grep "^LISTEN .*:$port\>") + l=$($SS -6 -a -n 2>/dev/null |grep "^sctp .*LISTEN .*:$port\>") else - l=$(netstat -an |grep '^sctp[6 ] .* [0-9a-f:]*:'$port' .* LISTEN') + l=$(netstat -an |grep '^sctp[6 ] .* \*:'$port' .* LISTEN') fi ;; # FreeBSD) l=$(netstat -an |grep -i 'tcp[46][6 ] .*[0-9*][:.]'$port' .* listen') ;; # NetBSD) l=$(netstat -an |grep '^tcp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; @@ -1770,7 +1936,7 @@ waitsctp6port () { # AIX) l=$(netstat -an |grep '^tcp[6 ] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; SunOS) l=$(netstat -an -f inet6 -P sctp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;; # #OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;; - *) l=$(netstat -an |grep -i 'stcp6 .*:'$port' .* listen') ;; + *) l=$(netstat -an |grep -i 'stcp6 .*:'$port' .* listen') ;; esac if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ \( \( $logic -eq 0 \) -a -z "$l" \) ]; then @@ -1831,6 +1997,45 @@ waitudplite6port () { return 1 } +# wait until a dccp6 listen port is ready +# not all (Linux) variants show this in netstat +waitdccp6port () { + local port="$1" + local logic="$2" # 0..wait until free; 1..wait until listening + local timeout="$3" + local l + local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here + [ "$logic" ] || logic=1 + [ "$timeout" ] || timeout=5 + while [ $timeout -gt 0 ]; do + case "$UNAME" in + Linux) if [ "$SS" ]; then + l=$($SS -6 -a -n 2>/dev/null |grep "^dccp .*LISTEN .*:$port\>") + else + l=$(netstat -an |grep '^dccp[6 ] .* [0-9a-f:]*:'$port' .* LISTEN') + fi ;; +# FreeBSD) l=$(netstat -an |grep -i 'tcp[46][6 ] .*[0-9*][:.]'$port' .* listen') ;; +# NetBSD) l=$(netstat -an |grep '^tcp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; +# OpenBSD) l=$(netstat -an |grep -i 'tcp6 .*[0-9*][:.]'$port' .* listen') ;; +# AIX) l=$(netstat -an |grep '^tcp[6 ] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; + SunOS) l=$(netstat -an -f inet6 -P dccp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;; +# #OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;; + *) l=$(netstat -an |grep -i 'stcp6 .*:'$port' .* listen') ;; + esac + if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ + \( \( $logic -eq 0 \) -a -z "$l" \) ]; then + set ${vx}vx + return 0 + fi + sleep $val_t + timeout=$((timeout-1)) + done + + $ECHO "!port $port timed out! \c" >&2 + set ${vx}vx + return 1 +} + # we need this misleading function name for canonical reasons waitunixport () { waitfile "$1" "$2" "$3" @@ -1874,6 +2079,26 @@ case "$UNAME" in *) SOCK_SEQPACKET=5 ;; esac + +HAVEDNS=1 +if [ "$INTERNET" ]; then + # No "-s 24" on Solaris + if ! ping -c 1 "9.9.9.9" >/dev/null 2>&1; then + echo "$0: Option --internet but no connectivity" >&2 + HAVEDNS= + elif type nslookup >/dev/null 2>&1; then + if ! nslookup server-4.dest-unreach.net. |grep '^Name:' >/dev/null 2>&1; then + echo "$0: Option --internet but broken DNS (cannot resolve server-4.dest-unreach.net)" >&2 + HAVEDNS= + fi + elif type host >/dev/null 2>&1; then + if ! host server-4.dest-unreach.net. |grep "has address" >/dev/null 2>&1; then + echo "$0: Option --internet but broken DNS (cannot resolve server-4.dest-unreach.net)" >&2 + HAVEDNS= + fi + fi +fi + # generate a test certificate and key gentestcert () { local name="$1" @@ -1937,7 +2162,7 @@ NAME=UNISTDIO case "$TESTS " in *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*) TEST="$NAME: unidirectional throughput from stdin to stdout" -testecho "$N" "$TEST" "stdin" "stdout" "$opts -u" +testecho "$N" "$NAME" "$TEST" "stdin" "stdout" "$opts -u" esac N=$((N+1)) @@ -1948,7 +2173,7 @@ NAME=UNPIPESTDIO case "$TESTS" in *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*) TEST="$NAME: stdio with simple echo via internal pipe" -testecho "$N" "$TEST" "stdio" "pipe" "$opts" +testecho "$N" "$NAME" "$TEST" "stdio" "pipe" "$opts" esac N=$((N+1)) @@ -1957,7 +2182,7 @@ NAME=UNPIPESHORT case "$TESTS" in *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*) TEST="$NAME: short form of stdio ('-') with simple echo via internal pipe" -testecho "$N" "$TEST" "-" "pipe" "$opts" +testecho "$N" "$NAME" "$TEST" "-" "pipe" "$opts" esac N=$((N+1)) @@ -1965,8 +2190,8 @@ N=$((N+1)) NAME=DUALSTDIO case "$TESTS" in *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*) -TEST="$NAME: splitted form of stdio ('stdin!!stdout') with simple echo via internal pipe" -testecho "$N" "$TEST" "stdin!!stdout" "pipe" "$opts" +TEST="$NAME: split form of stdio ('stdin!!stdout') with simple echo via internal pipe" +testecho "$N" "$NAME" "$TEST" "stdin!!stdout" "pipe" "$opts" esac N=$((N+1)) @@ -1974,8 +2199,8 @@ N=$((N+1)) NAME=DUALSHORTSTDIO case "$TESTS" in *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*) -TEST="$NAME: short splitted form of stdio ('-!!-') with simple echo via internal pipe" -testecho "$N" "$TEST" "-!!-" "pipe" "$opts" +TEST="$NAME: short split form of stdio ('-!!-') with simple echo via internal pipe" +testecho "$N" "$NAME" "$TEST" "-!!-" "pipe" "$opts" esac N=$((N+1)) @@ -1984,7 +2209,7 @@ NAME=DUALFDS case "$TESTS" in *%$N%*|*%functions%*|*%fd%*|*%$NAME%*) TEST="$NAME: file descriptors with simple echo via internal pipe" -testecho "$N" "$TEST" "0!!1" "pipe" "$opts" +testecho "$N" "$NAME" "$TEST" "0!!1" "pipe" "$opts" esac N=$((N+1)) @@ -1996,7 +2221,7 @@ TEST="$NAME: simple echo via named pipe" # with MacOS, this test hangs if nonblock is not used. Is an OS bug. tp="$td/pipe$N" # note: the nonblock is required by MacOS 10.1(?), otherwise it hangs (OS bug?) -testecho "$N" "$TEST" "" "pipe:$tp,nonblock" "$opts" +testecho "$N" "$NAME" "$TEST" "" "pipe:$tp,nonblock" "$opts" esac N=$((N+1)) @@ -2006,7 +2231,7 @@ case "$TESTS" in *%$N%*|*%functions%*|*%pipe%*|*%$NAME%*) TEST="$NAME: simple echo via named pipe, specified twice" tp="$td/pipe$N" -testecho "$N" "$TEST" "" "pipe:$tp,nonblock!!pipe:$tp" "$opts" +testecho "$N" "$NAME" "$TEST" "" "pipe:$tp,nonblock!!pipe:$tp" "$opts" esac N=$((N+1)) @@ -2016,7 +2241,7 @@ case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%file%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: simple echo via file" tf="$td/file$N" -testecho "$N" "$TEST" "" "$tf,ignoreeof!!$tf" "$opts" +testecho "$N" "$NAME" "$TEST" "" "$tf,ignoreeof!!$tf" "$opts" esac N=$((N+1)) @@ -2025,7 +2250,7 @@ NAME=EXECSOCKETPAIR case "$TESTS" in *%$N%*|*%functions%*|*%exec%*|*%socketpair%*|*%$NAME%*) TEST="$NAME: simple echo via exec of cat with socketpair" -testecho "$N" "$TEST" "" "EXEC:$CAT" "$opts" +testecho "$N" "$NAME" "$TEST" "" "EXEC:$CAT" "$opts" esac N=$((N+1)) @@ -2033,7 +2258,7 @@ NAME=SYSTEMSOCKETPAIR case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%socketpair%*|*%$NAME%*) TEST="$NAME: simple echo via system() of cat with socketpair" -testecho "$N" "$TEST" "" "SYSTEM:$CAT" "$opts" "$val_t" +testecho "$N" "$NAME" "$TEST" "" "SYSTEM:$CAT" "$opts" "$val_t" esac N=$((N+1)) @@ -2042,7 +2267,7 @@ NAME=EXECPIPES case "$TESTS" in *%$N%*|*%functions%*|*%exec%*|*%pipe%*|*%$NAME%*) TEST="$NAME: simple echo via exec of cat with pipes" -testecho "$N" "$TEST" "" "EXEC:$CAT,pipes" "$opts" +testecho "$N" "$NAME" "$TEST" "" "EXEC:$CAT,pipes" "$opts" esac N=$((N+1)) @@ -2050,7 +2275,7 @@ NAME=SYSTEMPIPES case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*) TEST="$NAME: simple echo via system() of cat with pipes" -testecho "$N" "$TEST" "" "SYSTEM:$CAT,pipes" "$opts" +testecho "$N" "$NAME" "$TEST" "" "SYSTEM:$CAT,pipes" "$opts" esac N=$((N+1)) @@ -2062,10 +2287,9 @@ TEST="$NAME: simple echo via exec of cat with pseudo terminal" if ! eval $NUMCOND; then :; elif ! testfeats pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else -testecho "$N" "$TEST" "" "EXEC:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts" +testecho "$N" "$NAME" "$TEST" "" "EXEC:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts" fi esac N=$((N+1)) @@ -2077,10 +2301,9 @@ TEST="$NAME: simple echo via system() of cat with pseudo terminal" if ! eval $NUMCOND; then :; elif ! testfeats pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else -testecho "$N" "$TEST" "" "SYSTEM:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts" +testecho "$N" "$NAME" "$TEST" "" "SYSTEM:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts" fi esac N=$((N+1)) @@ -2090,7 +2313,7 @@ NAME=SYSTEMPIPESFDS case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*) TEST="$NAME: simple echo via system() of cat with pipes, non stdio" -testecho "$N" "$TEST" "" "SYSTEM:$CAT>&9 <&8,pipes,fdin=8,fdout=9" "$opts" +testecho "$N" "$NAME" "$TEST" "" "SYSTEM:$CAT>&9 <&8,pipes,fdin=8,fdout=9" "$opts" esac N=$((N+1)) @@ -2099,12 +2322,12 @@ NAME=DUALSYSTEMFDS case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%socketpair%*|*%$NAME%*) TEST="$NAME: echo via dual system() of cat" -testecho "$N" "$TEST" "SYSTEM:$CAT>&6,fdout=6!!system:$CAT<&7,fdin=7" "" "$opts" "$val_t" +testecho "$N" "$NAME" "$TEST" "SYSTEM:$CAT>&6,fdout=6!!system:$CAT<&7,fdin=7" "" "$opts" "$val_t" esac N=$((N+1)) -# test: send EOF to exec'ed sub process, let it finish its operation, and +# test: send EOF to exec'ed sub process, let it finish its operation, and # check if the sub process returns its data before terminating. NAME=EXECSOCKETPAIRFLUSH # idea: have socat exec'ing od; send data and EOF, and check if the od'ed data @@ -2112,7 +2335,7 @@ NAME=EXECSOCKETPAIRFLUSH case "$TESTS" in *%$N%*|*%functions%*|*%exec%*|*%socketpair%*|*%$NAME%*) TEST="$NAME: call to od via exec with socketpair" -testod "$N" "$TEST" "" "EXEC:$OD_C" "$opts" +testod "$N" "$NAME" "$TEST" "" "EXEC:$OD_C" "$opts" esac N=$((N+1)) @@ -2120,7 +2343,7 @@ NAME=SYSTEMSOCKETPAIRFLUSH case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%socketpair%*|*%$NAME%*) TEST="$NAME: call to od via system() with socketpair" -testod "$N" "$TEST" "" "SYSTEM:$OD_C" "$opts" $val_t +testod "$N" "$NAME" "$TEST" "" "SYSTEM:$OD_C" "$opts" $val_t esac N=$((N+1)) @@ -2129,7 +2352,7 @@ NAME=EXECPIPESFLUSH case "$TESTS" in *%$N%*|*%functions%*|*%exec%*|*%pipes%*|*%$NAME%*) TEST="$NAME: call to od via EXEC with pipes" -testod "$N" "$TEST" "" "EXEC:$OD_C,pipes" "$opts" +testod "$N" "$NAME" "$TEST" "" "EXEC:$OD_C,pipes" "$opts" esac N=$((N+1)) @@ -2137,7 +2360,7 @@ NAME=SYSTEMPIPESFLUSH case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*) TEST="$NAME: call to od via system() with pipes" -testod "$N" "$TEST" "" "SYSTEM:$OD_C,pipes" "$opts" "$val_t" +testod "$N" "$NAME" "$TEST" "" "SYSTEM:$OD_C,pipes" "$opts" "$val_t" esac N=$((N+1)) @@ -2149,10 +2372,9 @@ N=$((N+1)) #TEST="$NAME: call to od via exec with pseudo terminal" #if ! testfeats pty >/dev/null; then # $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N -# numCANT=$((numCANT+1)) -# listCANT="$listCANT $N" +# cant #else -#testod "$N" "$TEST" "" "exec:$OD_C,pty,$PTYOPTS" "$opts" +#testod "$N" "$NAME" "$TEST" "" "exec:$OD_C,pty,$PTYOPTS" "$opts" #fi #esac #N=$((N+1)) @@ -2165,10 +2387,9 @@ N=$((N+1)) #TEST="$NAME: call to od via system() with pseudo terminal" #if ! testfeats pty >/dev/null; then # $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N -# numCANT=$((numCANT+1)) -# listCANT="$listCANT $N" +# cant #else -#testod "$N" "$TEST" "" "system:$OD_C,pty,$PTYOPTS" "$opts" +#testod "$N" "$NAME" "$TEST" "" "system:$OD_C,pty,$PTYOPTS" "$opts" #fi #esac #N=$((N+1)) @@ -2178,7 +2399,7 @@ NAME=SYSTEMPIPESFDSFLUSH case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*) TEST="$NAME: call to od via system() with pipes, non stdio" -testod "$N" "$TEST" "" "SYSTEM:$OD_C>&9 <&8,pipes,fdin=8,fdout=9" "$opts" "$val_t" +testod "$N" "$NAME" "$TEST" "" "SYSTEM:$OD_C>&9 <&8,pipes,fdin=8,fdout=9" "$opts" "$val_t" esac N=$((N+1)) @@ -2186,7 +2407,7 @@ NAME=DUALSYSTEMFDSFLUSH case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*) TEST="$NAME: call to od via dual system()" -testod "$N" "$TEST" "SYSTEM:$OD_C>&6,fdout=6!!SYSTEM:$CAT<&7,fdin=7" "pipe" "$opts" "$val_t" +testod "$N" "$NAME" "$TEST" "SYSTEM:$OD_C>&6,fdout=6!!SYSTEM:$CAT<&7,fdin=7" "pipe" "$opts" "$val_t" esac N=$((N+1)) @@ -2198,18 +2419,15 @@ TEST="$NAME: simple echo via self receiving raw IPv4 protocol" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testfeats rawip) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else - testecho "$N" "$TEST" "" "IP4:127.0.0.1:$IPPROTO" "$opts" + testecho "$N" "$NAME" "$TEST" "" "IP4:127.0.0.1:$IPPROTO" "$opts" fi esac N=$((N+1)) @@ -2221,18 +2439,15 @@ TEST="$NAME: simple echo via self receiving raw IP protocol, v4 by target" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testfeats rawip) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else - testecho "$N" "$TEST" "" "IP:127.0.0.1:$IPPROTO" "$opts" + testecho "$N" "$NAME" "$TEST" "" "IP:127.0.0.1:$IPPROTO" "$opts" fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -2244,18 +2459,15 @@ TEST="$NAME: simple echo via self receiving raw IPv6 protocol" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testfeats rawip) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else - testecho "$N" "$TEST" "" "IP6:[::1]:$IPPROTO" "$opts" + testecho "$N" "$NAME" "$TEST" "" "IP6:[::1]:$IPPROTO" "$opts" fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -2267,25 +2479,23 @@ TEST="$NAME: simple echo via self receiving raw IP protocol, v6 by target" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testfeats rawip) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else - testecho "$N" "$TEST" "" "IP:[::1]:$IPPROTO" "$opts" + testecho "$N" "$NAME" "$TEST" "" "IP:[::1]:$IPPROTO" "$opts" fi esac N=$((N+1)) newport() { - _PORT=$((_PORT+1)) + _PORT=$((_PORT+1)) while eval wait${1}port $_PORT 1 0 2>/dev/null; do _PORT=$((_PORT+1)); done + #while ! eval check${1}port $_PORT 2>/dev/null; do sleep 1; _PORT=$((_PORT+1)); done #echo "PORT=$_PORT" >&2 PORT=$_PORT } @@ -2297,12 +2507,11 @@ TEST="$NAME: echo via self connection of TCP IPv4 socket" if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux$NORMAL\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport tcp4 # provide free port number in $PORT #ts="127.0.0.1:$tsl" - testecho "$N" "$TEST" "" "TCP:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR,reuseaddr" "$opts" + testecho "$N" "$NAME" "$TEST" "" "TCP:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR,reuseaddr" "$opts" fi esac N=$((N+1)) @@ -2315,11 +2524,10 @@ case "$TESTS" in TEST="$NAME: echo via self connection of UDP IPv4 socket" if [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux$NORMAL\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp4 # provide free port number in $PORT - testecho "$N" "$TEST" "" "UDP:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR" "$opts" + testecho "$N" "$NAME" "$TEST" "" "UDP:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR" "$opts" fi esac fi # NUMCOND @@ -2333,16 +2541,14 @@ TEST="$NAME: echo via self connection of UDP IPv6 socket" if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats udp ip6 >/dev/null || ! runsudp6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/file$N" newport udp6 # provide free port number in $PORT - testecho "$N" "$TEST" "" "UDP6:[::1]:$PORT,sp=$PORT,bind=[::1]" "$opts" + testecho "$N" "$NAME" "$TEST" "" "UDP6:[::1]:$PORT,sp=$PORT,bind=[::1]" "$opts" fi esac N=$((N+1)) @@ -2356,7 +2562,7 @@ TEST="$NAME: echo via two unidirectional UDP IPv4 sockets" tf="$td/file$N" newport udp4; PORT1=$PORT # get free port newport udp4; PORT2=$PORT # get free port -testecho "$N" "$TEST" "" "UDP:127.0.0.1:$PORT2,sp=$PORT1!!UDP:127.0.0.1:$PORT1,sp=$PORT2" "$opts" +testecho "$N" "$NAME" "$TEST" "" "UDP:127.0.0.1:$PORT2,sp=$PORT1!!UDP:127.0.0.1:$PORT1,sp=$PORT2" "$opts" esac fi # NUMCOND N=$((N+1)) @@ -2392,8 +2598,7 @@ if [ "$rc2" -ne 0 ]; then echo "$CMD2" echo "rc=$rc2" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" @@ -2401,13 +2606,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" echo "$CMD2" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $bg 2>/dev/null esac @@ -2426,8 +2629,7 @@ elif ! cond=$(checkconds "" "" "" \ "so-reuseaddr" \ "tcp4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -2448,9 +2650,7 @@ if [ $? -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -2459,17 +2659,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid1 2>/dev/null wait @@ -2486,20 +2683,16 @@ TEST="$NAME: echo via connection to TCP V6 socket" if ! eval $NUMCOND; then :; elif ! F=$(testfeats IP6 TCP LISTEN STDIO PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs - TCP6-LISTEN PIPE STDIN STDOUT TCP6-CONNECT); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions so-reuseaddr ) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -2520,8 +2713,7 @@ if [ $? -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" echo "$CMD1 &" @@ -2530,16 +2722,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}2" >&2 echo diff: cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null fi @@ -2556,20 +2746,16 @@ TEST="$NAME: echo via connection to TCP socket, v4 by target" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO PIPE IP4 TCP LISTEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs TCP TCP-LISTEN STDIN STDOUT PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions pf) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -2590,9 +2776,7 @@ if [ $? -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" @@ -2600,17 +2784,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null fi @@ -2626,20 +2807,16 @@ TEST="$NAME: echo via connection to TCP socket, v6 by target" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO PIPE IP6 TCP LISTEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs TCP TCP-LISTEN STDIN STDOUT PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions pf) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -2660,9 +2837,7 @@ if [ $? -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" @@ -2670,17 +2845,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null fi @@ -2698,16 +2870,13 @@ TEST="$NAME: option ipv6-v6only=0 listens on IPv4" if ! eval $NUMCOND; then :; elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions ipv6-v6only); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -2727,18 +2896,15 @@ if [ $? -ne 0 ]; then echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null fi @@ -2755,16 +2921,13 @@ TEST="$NAME: option ipv6-v6only=1 does not listen on IPv4" if ! eval $NUMCOND; then :; elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions ipv6-v6only); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -2782,17 +2945,14 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -eq 0 ]; then $PRINTF "$FAILED:\n" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED:\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid; wait wait @@ -2808,16 +2968,13 @@ TEST="$NAME: env SOCAT_DEFAULT_LISTEN_IP for IPv4 preference on listen" if ! eval $NUMCOND; then :; elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats ip6 >/dev/null || ! runstcp6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions ipv6-v6only); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -2837,18 +2994,15 @@ if [ $? -ne 0 ]; then echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null; wait fi @@ -2862,12 +3016,10 @@ TEST="$NAME: env SOCAT_DEFAULT_LISTEN_IP for IPv6 preference on listen" if ! eval $NUMCOND; then :; elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -2888,8 +3040,7 @@ if [ $? -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED (diff):\n" echo "SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 &" @@ -2898,16 +3049,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}2" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null; wait fi @@ -2921,16 +3070,13 @@ TEST="$NAME: option -4 for IPv4 preference on listen" if ! eval $NUMCOND; then :; elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions ipv6-v6only); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -2950,18 +3096,15 @@ if [ $? -ne 0 ]; then echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null; wait fi @@ -2975,12 +3118,10 @@ TEST="$NAME: option -6 for IPv6 preference on listen" if ! eval $NUMCOND; then :; elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -3000,18 +3141,15 @@ if [ $? -ne 0 ]; then echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null; wait wait @@ -3026,16 +3164,13 @@ TEST="$NAME: pf=4 overrides option -6 on listen" if ! eval $NUMCOND; then :; elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions ipv6-v6only); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -3055,18 +3190,15 @@ if [ $? -ne 0 ]; then echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null; wait fi @@ -3080,12 +3212,10 @@ TEST="$NAME: pf=6 overrides option -4 on listen" if ! eval $NUMCOND; then :; elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -3105,18 +3235,15 @@ if [ $? -ne 0 ]; then echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null; wait fi ;; # NUMCOND, feats @@ -3145,26 +3272,25 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" rc2=$? kill $pid1 2>/dev/null; wait if [ $rc2 -ne 0 ]; then - $PRINTF "$FAILED: $TRACE $SOCAT:\n" + $PRINTF "$FAILED (rc2=$rc2)\n" echo "$CMD1 &" + cat "${te}1" >&2 echo "$CMD2" - cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + cat "${te}2" >&2 + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then - $PRINTF "$FAILED\n" + $PRINTF "$FAILED (diff)\n" echo "$CMD1 &" - cat "${te}1" + cat "${te}1" >&2 echo "$CMD2" - cat "${te}2" - cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + cat "${te}2" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -3178,8 +3304,7 @@ TEST="$NAME: echo via connection to UDP V6 socket" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -3197,22 +3322,25 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" rc2=$? kill $pid1 2>/dev/null; wait if [ $rc2 -ne 0 ]; then - $PRINTF "$FAILED: $TRACE $SOCAT:\n" + $PRINTF "$FAILED (rc2=$rc2)\n" echo "$CMD1 &" + cat "${te}1" >&2 echo "$CMD2" - cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + cat "${te}2" >&2 + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then - $PRINTF "$FAILED\n" - cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + $PRINTF "$FAILED (diff)\n" + echo "$CMD1 &" + cat "${te}1" >&2 + echo "$CMD2" + cat "${te}2" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # ! testfeats esac @@ -3237,18 +3365,15 @@ if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! diff "$tf1" "$tf2" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND esac @@ -3278,8 +3403,7 @@ if [ ! -p "$tp" ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else #echo "$da" >"$tp" # might hang forever echo "$da" >"$tp" & export pid=$!; (relsleep 1; kill $pid 2>/dev/null) & @@ -3295,13 +3419,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" fi - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi wait @@ -3336,8 +3458,7 @@ if [ $? -ne 0 ]; then cat "${te}s" echo "$CMD" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then kill "$pids" 2>/dev/null $PRINTF "$FAILED:\n" @@ -3346,13 +3467,11 @@ elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then echo "$CMD" cat "${te}1" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # !(rc -ne 0) wait fi # NUMCOND @@ -3385,8 +3504,7 @@ if [ $? -ne 0 ]; then cat "${te}s" echo "$CMD" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then kill "$pids" 2>/dev/null $PRINTF "$FAILED:\n" @@ -3395,13 +3513,11 @@ elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then echo "$CMD" cat "${te}1" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # !(rc -ne 0) wait fi # NUMCOND @@ -3435,8 +3551,7 @@ if [ $? -ne 0 ]; then cat "${te}s" echo "$CMD" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da1" |diff - "${tf}" >"$tdiff"; then $PRINTF "$FAILED:\n" echo "$SRV &" @@ -3444,13 +3559,11 @@ elif ! echo "$da1" |diff - "${tf}" >"$tdiff"; then echo "$CMD" cat "${te}1" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # !(rc -ne 0) kill "$pids" 2>/dev/null; wait fi ;; # NUMCOND @@ -3458,71 +3571,108 @@ esac N=$((N+1)) +# Test the ignoreeof option in forward (left to right) direction NAME=IGNOREEOF case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: ignoreeof on file" -if ! eval $NUMCOND; then :; else +# Let Socat read from an empty file, this would terminate immediately due to +# EOF. Wait for more than one second, then append data to the file; when Socat +# transfers this data the test succeeded. +if ! eval $NUMCOND; then :; +elif ! cond=$(checkconds \ + "" \ + "" \ + "" \ + "STDIO FILE" \ + "STDOUT FILE" \ + "ignoreeof" \ + "" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant +else ti="$td/test$N.file" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" -CMD="$TRACE $SOCAT $opts -u file:\"$ti\",ignoreeof -" +# Note: the bug in 1.8.0.0 and 1.8.0.1 let Socat terminate in unidirectional +# mode after 1s, in bidirectional mode with traffic in reverse direction +# (var wasaction) immediately +CMD="$TRACE $SOCAT $opts -u FILE:\"$ti\",ignoreeof -" printf "test $F_n $TEST... " $N touch "$ti" $CMD >"$tf" 2>"$te" & bg=$! -sleep 0.1 +# Up to 1.8.0.1 this sleep was 0.1 and thus the test said OK despite the bug +sleep 1.1 echo "$da" >>"$ti" sleep 1 kill $bg 2>/dev/null; wait if ! echo "$da" |diff - "$tf" >"$tdiff"; then - $PRINTF "$FAILED: diff:\n" - cat "$tdiff" - listFAIL="$listFAIL $N" - numFAIL=$((numFAIL+1)) + $PRINTF "$FAILED (diff)\n" + echo "$CMD" + cat "$te" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + failed else - $PRINTF "$OK\n" - if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + $PRINTF "$OK\n" + if [ -n "$VERBOSE" ]; then echo "$CMD"; fi + if [ -n "$DEBUG" ]; then cat "$te" >&2; fi + ok fi fi ;; # NUMCOND esac N=$((N+1)) +# Test the ignoreeof option in reverse (right to left) direction NAME=IGNOREEOF_REV case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: ignoreeof on file right-to-left" -if ! eval $NUMCOND; then :; else +if ! eval $NUMCOND; then :; +elif ! cond=$(checkconds \ + "" \ + "" \ + "" \ + "STDIO FILE" \ + "STDOUT FILE" \ + "ignoreeof" \ + "" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant +else +# Let Socat read from an empty file, this would terminate immediately due to +# EOF. Wait for more than one second, then append data to the file; when Socat +# transfers this data the test succeeded. ti="$td/test$N.file" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" -CMD="$SOCAT $opts -U - file:\"$ti\",ignoreeof" +CMD="$SOCAT $opts -U - FILE:\"$ti\",ignoreeof" printf "test $F_n $TEST... " $N touch "$ti" $CMD >"$tf" 2>"$te" & bg=$! -relsleep 1 +sleep 1.1 echo "$da" >>"$ti" sleep 1 -kill $bg 2>/dev/null +kill $bg 2>/dev/null; wait if ! echo "$da" |diff - "$tf" >"$tdiff"; then - $PRINTF "$FAILED: diff:\n" - cat "$tdiff" - listFAIL="$listFAIL $N" - numFAIL=$((numFAIL+1)) + $PRINTF "$FAILED (diff)\n" + echo "$CMD" + cat "$te" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + failed else - $PRINTF "$OK\n" - if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + $PRINTF "$OK\n" + if [ -n "$VERBOSE" ]; then echo "$CMD"; fi + if [ -n "$DEBUG" ]; then cat "$te" >&2; fi + ok fi -wait fi ;; # NUMCOND esac N=$((N+1)) @@ -3542,14 +3692,13 @@ $CMD >"$tf" 2>"$te" if [ -s "$te" ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" - cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + cat "$te" >&2 + failed else - $PRINTF "$OK\n" - if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + $PRINTF "$OK\n" + if [ -n "$VERBOSE" ]; then echo "$CMD"; fi + if [ -n "$DEBUG" ]; then cat "$te" >&2; fi + ok fi fi ;; # NUMCOND esac @@ -3563,8 +3712,7 @@ TEST="$NAME: generation of pty for other processes" if ! eval $NUMCOND; then :; elif ! testfeats pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tt="$td/pty$N" tf="$td/test$N.stdout" @@ -3590,13 +3738,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null; wait fi ;; # NUMCOND, feats @@ -3625,13 +3771,11 @@ if ! [ $rc0 = 0 ] || echo "$CMD" cat "$te" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -3657,13 +3801,11 @@ if ! echo "$da" |$CMD >$tf 2>"$te" || echo "$CMD" cat "$te" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -3674,7 +3816,7 @@ NAME=RIGHTTOLEFT case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: unidirectional throughput from stdin to stdout, right to left" -testecho "$N" "$TEST" "stdout" "stdin" "$opts -U" +testecho "$N" "$NAME" "$TEST" "stdout" "stdin" "$opts -U" esac N=$((N+1)) @@ -3686,12 +3828,10 @@ case "$TESTS" in if ! eval $NUMCOND; then : elif ! F=$(testfeats STDIO EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else TEST="$NAME: child process default properties" tf="$td/test$N.stdout" @@ -3711,14 +3851,12 @@ then $PRINTF "$FAILED:\n" echo "$CMD" cat "$te" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD"; fi if [ "$DEBUG" ]; then cat "${te}" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -3747,12 +3885,10 @@ then $PRINTF "$FAILED\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -3781,12 +3917,10 @@ then $PRINTF "$FAILED\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -3800,16 +3934,13 @@ TEST="$NAME: openssl connect" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! type openssl >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -3835,13 +3966,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null; wait fi ;; # NUMCOND, feats @@ -3856,12 +3985,10 @@ TEST="$NAME: openssl listen" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -3883,13 +4010,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -3904,12 +4029,10 @@ TEST="$NAME: openssl listen" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -3931,13 +4054,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -3946,8 +4067,6 @@ esac N=$((N+1)) -newport $RUNS # in case it has not yet been invoked - while read NAMEKEYW FEAT RUNS TESTTMPL PEERTMPL WAITTMPL; do if [ -z "$NAMEKEYW" ] || [[ "$NAMEKEYW" == \#* ]]; then continue; fi @@ -3970,12 +4089,10 @@ TEST="$NAME: $TESTKEYW half close" if ! eval $NUMCOND; then :; elif [ "$FEAT" != ',' ] && ! testfeats "$FEAT" >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $FEAT not configured${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runs$RUNS >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$RUNS not available on host${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -3998,8 +4115,7 @@ if ! echo "$da" |$OD_C |diff - "$tf" >"$tdiff"; then echo "$CMD" cat "${te}" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then @@ -4007,8 +4123,7 @@ else echo " $CMD" fi if [ -n "$debug" ]; then cat "${te}2" "${te}"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi wait fi ;; # NUMCOND, feats @@ -4038,12 +4153,10 @@ TEST="$NAME: OpenSSL server authentication (hostname)" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv gentestcert testcli @@ -4066,13 +4179,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD1" cat "${te}1" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -4087,12 +4198,10 @@ TEST="$NAME: openssl client authentication" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv gentestcert testcli @@ -4115,13 +4224,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -4136,16 +4243,13 @@ TEST="$NAME: OpenSSL+FIPS client and server authentication" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testoptions fips >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL/FIPS not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else OPENSSL_FIPS=1 gentestcert testsrvfips OPENSSL_FIPS=1 gentestcert testclifips @@ -4168,13 +4272,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -4190,16 +4292,13 @@ TEST="$NAME: OpenSSL compression" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testoptions openssl-compress >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL compression option not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv printf "test $F_n $TEST... " $N @@ -4231,63 +4330,73 @@ else cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac N=$((N+1)) +# Test the SOCKS address with IPv4 NAME=SOCKS4CONNECT_TCP4 case "$TESTS" in *%$N%*|*%functions%*|*%socks%*|*%socks4%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*) TEST="$NAME: socks4 connect over TCP/IPv4" if ! eval $NUMCOND; then :; -elif ! testfeats socks4 >/dev/null; then - $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then - $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" +elif ! cond=$(checkconds \ + "" \ + "" \ + "socks4echo.sh" \ + "SOCKS4 IP4 TCP LISTEN STDIO" \ + "TCP4-LISTEN EXEC STDIN SOCKS4" \ + "so-reuseaddr" \ + "tcp4" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant else -tf="$td/test$N.stdout" -te="$td/test$N.stderr" -tdiff="$td/test$N.diff" -da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" -# we have a normal tcp echo listening - so the socks header must appear in answer -newport tcp4 # provide free port number in $PORT -CMD2="$TRACE $SOCAT $opts TCP4-L:$PORT,$REUSEADDR EXEC:\"./socks4echo.sh\"" -CMD="$TRACE $SOCAT $opts - SOCKS4:$LOCALHOST:32.98.76.54:32109,pf=ip4,socksport=$PORT",socksuser="nobody" -printf "test $F_n $TEST... " $N -eval "$CMD2 2>\"${te}1\" &" -pid=$! # background process id -waittcp4port $PORT 1 -echo "$da" |$CMD >$tf 2>"${te}2" -if ! echo "$da" |diff - "$tf" >"$tdiff"; then - $PRINTF "$FAILED: $TRACE $SOCAT:\n" - echo "$CMD2 &" - echo "$CMD" - cat "${te}1" - cat "${te}2" - cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" -else - $PRINTF "$OK\n" - if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" -fi -kill $pid 2>/dev/null -wait + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" + newport tcp4 # provide free port number in $PORT + CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,$REUSEADDR EXEC:\"./socks4echo.sh\"" + CMD1="$TRACE $SOCAT $opts STDIO SOCKS4:$LOCALHOST:32.98.76.54:32109,pf=ip4,socksport=$PORT",socksuser="nobody" + printf "test $F_n $TEST... " $N + eval "$CMD0 2>\"${te}0\" &" + pid0=$! # background process id + waittcp4port $PORT 1 + echo "$da" |$CMD1 >${tf}1 2>"${te}1" + rc1=$? + kill $pid0 2>/dev/null + wait + if [ "$rc1" -ne 0 ]; then + $PRINTF "$FAILED (rc1=$rc1)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + failed + elif ! echo "$da" |diff - "${tf}1" >"$tdiff"; then + $PRINTF "$FAILED (diff)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + failed + else + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok + fi fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -4299,12 +4408,10 @@ TEST="$NAME: socks4 connect over TCP/IPv6" if ! eval $NUMCOND; then :; elif ! testfeats socks4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -4327,16 +4434,14 @@ if ! echo "$da" |diff - "${tf}1" >"$tdiff"; then cat "${te}1" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -4352,12 +4457,10 @@ TEST="$NAME: socks4a connect over TCP/IPv4" if ! eval $NUMCOND; then :; elif ! testfeats socks4a >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -4379,13 +4482,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -4400,12 +4501,10 @@ TEST="$NAME: socks4a connect over TCP/IPv6" if ! eval $NUMCOND; then :; elif ! testfeats socks4a >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -4427,13 +4526,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -4449,44 +4546,52 @@ TEST="$NAME: proxy connect over TCP/IPv4" if ! eval $NUMCOND; then :; elif ! testfeats proxy >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else -ts="$td/test$N.sh" -tf="$td/test$N.stdout" -te="$td/test$N.stderr" -tdiff="$td/test$N.diff" -da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" -newport tcp4 # provide free port number in $PORT -#CMD2="$TRACE $SOCAT tcp4-l:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\"" -CMD2="$TRACE $SOCAT $opts TCP4-L:$PORT,$REUSEADDR,crlf EXEC:\"/usr/bin/env bash proxyecho.sh\"" -CMD="$TRACE $SOCAT $opts - PROXY:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT" -printf "test $F_n $TEST... " $N -eval "$CMD2 2>\"${te}2\" &" -pid=$! # background process id -waittcp4port $PORT 1 -echo "$da" |$CMD >"$tf" 2>"${te}1" -if ! echo "$da" |diff - "$tf" >"$tdiff"; then - $PRINTF "$FAILED: $TRACE $SOCAT:\n" - echo "$CMD2 &" - echo "$CMD" - cat "${te}1" - cat "${te}2" - cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" -else - $PRINTF "$OK\n" - if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" -fi -kill $pid 2>/dev/null -wait + ts="$td/test$N.sh" + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" + newport tcp4 # provide free port number in $PORT + #CMD0="$TRACE $SOCAT tcp4-l:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\"" + CMD0="$TRACE $SOCAT $opts TCP4-L:$PORT,$REUSEADDR,crlf EXEC:\"/usr/bin/env bash proxyecho.sh\"" + CMD1="$TRACE $SOCAT $opts - PROXY:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT" + printf "test $F_n $TEST... " $N + eval "$CMD0 2>\"${te}0\" &" + pid=$! # background process id + waittcp4port $PORT 1 + echo "$da" |$CMD1 >"$tf" 2>"${te}1" + rc1=$? + if [ "$rc1" -ne 0 ]; then + $PRINTF "$FAILED (rc1=$rc1)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + fail + elif ! echo "$da" |diff - "$tf" >"$tdiff"; then + $PRINTF "$FAILED (diff)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + fail + else + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok + fi + kill $pid 2>/dev/null + wait fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -4498,44 +4603,52 @@ TEST="$NAME: proxy connect over TCP/IPv6" if ! eval $NUMCOND; then :; elif ! testfeats proxy >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else -ts="$td/test$N.sh" -tf="$td/test$N.stdout" -te="$td/test$N.stderr" -tdiff="$td/test$N.diff" -da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" -newport tcp6 # provide free port number in $PORT -#CMD2="$TRACE $SOCAT $opts TCP6-L:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\"" -CMD2="$TRACE $SOCAT $opts TCP6-L:$PORT,$REUSEADDR,crlf EXEC:\"/usr/bin/env bash proxyecho.sh\"" -CMD="$TRACE $SOCAT $opts - PROXY:$LOCALHOST6:127.0.0.1:1000,proxyport=$PORT" -printf "test $F_n $TEST... " $N -eval "$CMD2 2>\"${te}2\" &" -pid=$! # background process id -waittcp6port $PORT 1 -echo "$da" |$CMD >"$tf" 2>"${te}1" -if ! echo "$da" |diff - "$tf" >"$tdiff"; then - $PRINTF "$FAILED: $TRACE $SOCAT:\n" - echo "$CMD2 &" - echo "$CMD" - cat "${te}1" - cat "${te}2" - cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" -else - $PRINTF "$OK\n" - if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" -fi -kill $pid 2>/dev/null -wait + ts="$td/test$N.sh" + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" + newport tcp6 # provide free port number in $PORT + #CMD0="$TRACE $SOCAT $opts TCP6-L:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\"" + CMD0="$TRACE $SOCAT $opts TCP6-L:$PORT,$REUSEADDR,crlf EXEC:\"/usr/bin/env bash proxyecho.sh\"" + CMD1="$TRACE $SOCAT $opts - PROXY:$LOCALHOST6:127.0.0.1:1000,proxyport=$PORT" + printf "test $F_n $TEST... " $N + eval "$CMD0 2>\"${te}0\" &" + pid=$! # background process id + waittcp6port $PORT 1 + echo "$da" |$CMD1 >"$tf" 2>"${te}1" + rc1=$? + if [ "$rc1" -ne 0 ]; then + $PRINTF "$FAILED (rc1=$rc1)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + failed + elif ! echo "$da" |diff - "$tf" >"$tdiff"; then + $PRINTF "$FAILED (diff)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + echo "// diff: " >&2 + cat "$tdiff" >&2 + failed + else + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok + fi + kill $pid 2>/dev/null + wait fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -4566,18 +4679,15 @@ if [ $? -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -4588,7 +4698,7 @@ NAME=EXECCATNOFORK case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: simple echo via exec of cat with nofork" -testecho "$N" "$TEST" "" "EXEC:$CAT,nofork" "$opts" +testecho "$N" "$NAME" "$TEST" "" "EXEC:$CAT,nofork" "$opts" esac N=$((N+1)) @@ -4597,7 +4707,7 @@ NAME=SYSTEMCATNOFORK case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: simple echo via system() of cat with nofork" -testecho "$N" "$TEST" "" "SYSTEM:$CAT,nofork" "$opts" +testecho "$N" "$NAME" "$TEST" "" "SYSTEM:$CAT,nofork" "$opts" esac N=$((N+1)) @@ -4606,7 +4716,7 @@ NAME=NOFORKSETSID case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: simple echo via exec() of cat with nofork and setsid" -testecho "$N" "$TEST" "" "SYSTEM:$CAT,nofork,setsid" "$opts" +testecho "$N" "$NAME" "$TEST" "" "SYSTEM:$CAT,nofork,setsid" "$opts" esac N=$((N+1)) @@ -4622,12 +4732,10 @@ N=$((N+1)) #echo "$da" |$TRACE $SOCAT stdin!!stdout UDP:$ts >"$tf" #if [ $? -eq 0 ] && echo "$da" |diff "$tf" -; then # $ECHO "... test $N succeeded" -# numOK=$((numOK+1)) -# listOK="$listOK $N" +# ok #else # $ECHO "*** test $N $FAILED" -# numFAIL=$((numFAIL+1)) -# listFAIL="$listFAIL $N" +# failed #fi #fi ;; # NUMCOND #N=$((N+1)) @@ -4642,12 +4750,10 @@ N=$((N+1)) #echo "$da" |$TRACE $SOCAT - FILE:$tf.tmp,ignoreeof >"$tf" #if [ $? -eq 0 ] && echo "$da" |diff "$tf" -; then # $ECHO "... test $N succeeded" -# numOK=$((numOK+1)) -# listOK="$listOK $N" +# ok #else # $ECHO "*** test $N $FAILED" -# numFAIL=$((numFAIL+1)) -# listFAIL="$listFAIL $N" +# failed #fi #fi ;; # NUMCOND @@ -4678,13 +4784,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -4724,13 +4828,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "$te" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "$te"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi wait MICROS=$SAVEMICS @@ -4746,8 +4848,7 @@ TEST="$NAME: proxy connect accepts status with multiple spaces" if ! eval $NUMCOND; then :; elif ! testfeats proxy >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ts="$td/test$N.sh" tf="$td/test$N.stdout" @@ -4771,16 +4872,14 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" >&2 echo "diff:" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$debug" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$debug" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -4804,19 +4903,16 @@ CMD="$TRACE $SOCAT $opts -u /dev/null -,setlk" $CMD <"$ff" 2>"$te" if [ "$?" -eq 0 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else if [ "$UNAME" = "Linux" ]; then $PRINTF "$FAILED\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "${YELLOW}failed (don't care)${NORMAL}\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant fi fi fi ;; # NUMCOND @@ -4828,7 +4924,7 @@ NAME=SINGLEEXECOUTSOCKETPAIR case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: inheritance of stdout to single exec with socketpair" -testecho "$N" "$TEST" "-!!exec:cat" "" "$opts" 1 +testecho "$N" "$NAME" "$TEST" "-!!exec:cat" "" "$opts" 1 esac N=$((N+1)) @@ -4836,7 +4932,7 @@ NAME=SINGLEEXECOUTPIPE case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: inheritance of stdout to single exec with pipe" -testecho "$N" "$TEST" "-!!exec:cat,pipes" "" "$opts" 1 +testecho "$N" "$NAME" "$TEST" "-!!exec:cat,pipes" "" "$opts" 1 esac N=$((N+1)) @@ -4847,10 +4943,9 @@ TEST="$NAME: inheritance of stdout to single exec with pty" if ! eval $NUMCOND; then :; elif ! testfeats pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else -testecho "$N" "$TEST" "-!!exec:cat,pty,raw" "" "$opts" 1 +testecho "$N" "$NAME" "$TEST" "-!!exec:cat,pty,raw" "" "$opts" 1 fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -4859,7 +4954,7 @@ NAME=SINGLEEXECINSOCKETPAIR case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: inheritance of stdin to single exec with socketpair" -testecho "$N" "$TEST" "exec:cat!!-" "" "$opts" +testecho "$N" "$NAME" "$TEST" "exec:cat!!-" "" "$opts" esac N=$((N+1)) @@ -4867,7 +4962,7 @@ NAME=SINGLEEXECINPIPE case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: inheritance of stdin to single exec with pipe" -testecho "$N" "$TEST" "exec:cat,pipes!!-" "" "$opts" +testecho "$N" "$NAME" "$TEST" "exec:cat,pipes!!-" "" "$opts" esac N=$((N+1)) @@ -4878,10 +4973,9 @@ TEST="$NAME: inheritance of stdin to single exec with pty, with delay" if ! eval $NUMCOND; then :; elif ! testfeats pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else -testecho "$N" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" $MISCDELAY +testecho "$N" "$NAME" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" $MISCDELAY fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -4893,11 +4987,10 @@ TEST="$NAME: inheritance of stdin to single exec with pty" if ! eval $NUMCOND; then :; elif ! testfeats pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else # T value needed (only) by AIX -testecho "$N" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" 0.1 +testecho "$N" "$NAME" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" 0.1 fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -4911,8 +5004,7 @@ TEST="$NAME: readline with password and sigint" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats readline pty); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else SAVETERM="$TERM"; TERM= # 'cause console might print controls even in raw SAVEMICS=$MICROS @@ -4925,8 +5017,9 @@ te="$td/test$N.stderr" tr="$td/test$N.ref" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" -# the feature that we really want to test is in the readline.sh script: -CMD="$TRACE $SOCAT -lpwrapper $opts -t1 open:$tpi,nonblock!!open:$tpo exec:\"./readline.sh -nh ./readline-test.sh\",pty,ctty,setsid,raw,echo=0,isig" +# The feature that we really want to test is in the readline.sh script +READLINE_LOG=; if grep -e -lf ./readline.sh >/dev/null; then READLINE_LOG="-lf $td/test$N.rl-log"; fi +CMD="$TRACE $SOCAT -lpwrapper $opts -t1 OPEN:$tpi,nonblock!!OPEN:$tpo EXEC:\"./readline.sh -nh $READLINE_LOG ./readline-test.sh\",pty,ctty,setsid,raw,echo=0,isig" #echo "$CMD" >"$ts" #chmod a+x "$ts" printf "test $F_n $TEST... " $N @@ -4984,14 +5077,12 @@ if ! tr "$($ECHO '\r \c')" "% " <$tpo |sed 's/%$//g' |sed 's/.*%//g' |diff "$tr" cat "$te" 2>&1 echo diff: 2>&1 cat "$tdiff" 2>&1 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi wait MICROS=$SAVEMICS @@ -5003,7 +5094,7 @@ N=$((N+1)) NAME=GENDERCHANGER case "$TESTS" in -*%$N%*|*%functions%*|*%listen%*|*%$NAME%*) +*%$N%*|*%functions%*|*%listen%*|*%retry%*|*%$NAME%*) TEST="$NAME: TCP4 \"gender changer\"" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" @@ -5046,8 +5137,7 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}4" >&2 echo diff: >&2 cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi @@ -5058,8 +5148,7 @@ else if [ "$DEBUG" ]; then cat "${te}3" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD4"; fi if [ "$DEBUG" ]; then cat "${te}4" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -5068,13 +5157,12 @@ N=$((N+1)) NAME=OUTBOUNDIN case "$TESTS" in -*%$N%*|*%functions%*|*%openssl%*|*%proxy%*|*%fork%*|*%listen%*|*%$NAME%*) +*%$N%*|*%functions%*|*%openssl%*|*%proxy%*|*%fork%*|*%listen%*|*%retry%*|*%$NAME%*) TEST="$NAME: gender changer via SSL through HTTP proxy, oneshot" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats openssl proxy); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv gentestcert testcli @@ -5134,13 +5222,11 @@ if ! (echo "$da"; sleep 2) |diff - "$tf" >"$tdiff"; then echo "$CMD4 &" cat "${te}4" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4" "${te}5" "${te}6"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null wait @@ -5160,13 +5246,12 @@ N=$((N+1)) #! NAME=INTRANETRIPPER case "$TESTS" in -*%$N%*|*%functions%*|*%openssl%*|*%proxy%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%openssl%*|*%proxy%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: gender changer via SSL through HTTP proxy, daemons" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats openssl proxy); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv gentestcert testcli @@ -5182,11 +5267,12 @@ newport tcp4; PORT3=$PORT newport tcp4; PORT4=$PORT newport tcp4; PORT5=$PORT # this is the server in the protected network that we want to reach -CMD1="$TRACE $SOCAT $opts -lpserver -t$(reltime 10) TCP4-L:$PORT1,reuseaddr,bind=$LOCALHOST,fork ECHO" +CMD1="$TRACE $SOCAT $opts -lpserver -t$(reltime 100) TCP4-L:$PORT1,reuseaddr,bind=$LOCALHOST,fork ECHO" # this is the proxy in the protected network that provides a way out # note: the proxy.sh script starts one or two more socat processes without # setting the program name -CMD2="$TRACE $SOCAT $opts -lpproxy -t$(reltime 10) TCP4-L:$PORT2,reuseaddr,bind=$LOCALHOST,fork EXEC:./proxy.sh" +export SOCAT_OPTS="$OPTS" # for proxy.sh +CMD2="$TRACE $SOCAT $opts -lpproxy -t$(reltime 100) TCP4-L:$PORT2,reuseaddr,bind=$LOCALHOST,fork EXEC:./proxy.sh" # this is our proxy connect wrapper in the protected network CMD3="$TRACE $SOCAT $opts -lpwrapper -t$(reltime 30) TCP4-L:$PORT3,reuseaddr,bind=$LOCALHOST,fork PROXY:$LOCALHOST:$LOCALHOST:$PORT4,pf=ip4,proxyport=$PORT2,resolve" # this is our double client in the protected network using SSL @@ -5212,21 +5298,23 @@ waittcp4port $PORT3 1 50 || $PRINTF "$FAILED: port $PORT3\n" >&2 </dev/null # now we start the external daemon eval "$CMD5 2>\"${te}5\" &" pid5=$! -waittcp4port $PORT5 1 50 || $PRINTF "$FAILED: port $5PORT\n" >&2 </dev/null +waittcp4port $PORT5 1 50 || $PRINTF "$FAILED: port $PORT5\n" >&2 </dev/null # and this is the outside client: -echo "$da1" |$CMD6 >${tf}_1 2>"${te}6_1" & +{ echo "$da1"; relsleep 100; } |$CMD6 >${tf}_1 2>"${te}6_1" & pid6_1=$! -echo "$da2" |$CMD6 >${tf}_2 2>"${te}6_2" & +relsleep 20 +{ echo "$da2"; relsleep 100; } |$CMD6 >${tf}_2 2>"${te}6_2" & pid6_2=$! -echo "$da3" |$CMD6 >${tf}_3 2>"${te}6_3" & +relsleep 20 +{ echo "$da3"; relsleep 100; } |$CMD6 >${tf}_3 2>"${te}6_3" & pid6_3=$! wait $pid6_1 $pid6_2 $pid6_3 kill $pid1 $pid2 $pid3 $pid4 $pid5 $(childpids $pid5) 2>/dev/null -# (On BSDs a child of pid5 loves to hang) +# (On BSDs a child of pid5 likes to hang) # -(echo "$da1"; relsleep 2) |diff - "${tf}_1" >"${tdiff}1" -(echo "$da2"; relsleep 2) |diff - "${tf}_2" >"${tdiff}2" -(echo "$da3"; relsleep 2) |diff - "${tf}_3" >"${tdiff}3" +echo "$da1" |diff - "${tf}_1" >"${tdiff}1" +echo "$da2" |diff - "${tf}_2" >"${tdiff}2" +echo "$da3" |diff - "${tf}_3" >"${tdiff}3" if test -s "${tdiff}1" -o -s "${tdiff}2" -o -s "${tdiff}3"; then # FAILED only when none of the three transfers succeeded if test -s "${tdiff}1" -a -s "${tdiff}2" -a -s "${tdiff}3"; then @@ -5250,19 +5338,16 @@ if test -s "${tdiff}1" -o -s "${tdiff}2" -o -s "${tdiff}3"; then echo "$CMD6 &" cat "${te}6_3" cat "${tdiff}3" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK ${YELLOW}(partial failure)${NORMAL}\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4" "${te}5" ${te}6*; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4" "${te}5" ${te}6*; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null wait @@ -5306,8 +5391,7 @@ testserversec () { $PRINTF "$NO_RESULT (ph.1 server not working):\n" echo "$TRACE $SOCAT $opts \"$arg1,$secopt0\" echo &" cat "${te}1" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant wait; return fi # now use client @@ -5321,8 +5405,7 @@ testserversec () { cat "${te}1" echo "$TRACE $SOCAT $opts - \"$arg2\"" cat "${te}2" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant wait; return elif echo "$da" |diff - "$tf" >"$tdiff1" 2>&1; then : # function without security is ok, go on @@ -5333,16 +5416,14 @@ testserversec () { echo "$TRACE $SOCAT $opts - $arg2" cat "${te}2" cat "$tdiff1" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant wait; return fi # then: with security if [ "$port" ] && ! wait${proto}${ipvers}port $port 0; then $PRINTF "$NO_RESULT (ph.1 port remains in use)\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant wait; return fi wait @@ -5364,8 +5445,7 @@ testserversec () { wait echo "$CMD3" cat "${te}3" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant return fi # now use client @@ -5391,8 +5471,7 @@ testserversec () { echo "$TRACE $SOCAT $opts - $arg2" cat "${te}4" cat "$tdiff2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif [ "X$expect" != 'X*' -a X$result != X$expect ]; then case X$result in X-1) $PRINTF "$NO_RESULT (ph.2 client error): $TRACE $SOCAT:\n" @@ -5400,8 +5479,7 @@ testserversec () { cat "${te}3" echo "$TRACE $SOCAT $opts - $arg2" cat "${te}4" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant ;; X0) $PRINTF "$NO_RESULT (ph.2 diff failed): diff:\n" echo "$TRACE $SOCAT $opts $arg echo" @@ -5409,8 +5487,7 @@ testserversec () { echo "$TRACE $SOCAT $opts - $arg2" cat "${te}4" cat "$tdiff2" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant ;; X1) $PRINTF "$FAILED: SECURITY BROKEN\n" echo "$TRACE $SOCAT $opts $arg echo" @@ -5418,8 +5495,7 @@ testserversec () { echo "$TRACE $SOCAT $opts - $arg2" cat "${te}4" cat "$tdiff2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed ;; X2) $PRINTF "$FAILED: diff:\n" echo "$TRACE $SOCAT $opts $arg echo" @@ -5427,8 +5503,7 @@ testserversec () { echo "$TRACE $SOCAT $opts - $arg2" cat "${te}4" cat "$tdiff2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed ;; esac else @@ -5437,8 +5512,7 @@ testserversec () { [ "$debug" ] && cat ${te}3 [ "$VERBOSE" ] && echo " $TRACE $SOCAT $opts - $arg2" [ "$debug" ] && cat ${te}4 - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi wait #set +vx @@ -5447,14 +5521,13 @@ testserversec () { NAME=TCP4RANGEBITS case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with RANGE option" if ! eval $NUMCOND; then :; elif [ -z "$SECONDADDR" ]; then # we need access to a second addresses $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport tcp4 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "TCP4-L:$PORT,reuseaddr,fork,retry=1" "" "range=$SECONDADDR/32" "TCP4:127.0.0.1:$PORT" 4 tcp $PORT 0 @@ -5464,14 +5537,13 @@ N=$((N+1)) NAME=TCP4RANGEMASK case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with RANGE option" if ! eval $NUMCOND; then :; elif [ -z "$SECONDADDR" ]; then # we need access to a second addresses $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport tcp4 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "TCP4-L:$PORT,reuseaddr,fork,retry=1" "" "range=$SECONDADDR:255.255.255.255" "TCP4:127.0.0.1:$PORT" 4 tcp $PORT 0 @@ -5482,7 +5554,7 @@ N=$((N+1)) # like TCP4RANGEMASK, but the "bad" address is within the same class A network NAME=TCP4RANGEMASKHAIRY case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with RANGE option" if ! eval $NUMCOND; then :; else newport tcp4 # provide free port number in $PORT @@ -5494,7 +5566,7 @@ N=$((N+1)) NAME=TCP4SOURCEPORT case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%sourceport%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%sourceport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with SOURCEPORT option" if ! eval $NUMCOND; then :; else newport tcp4 # provide free port number in $PORT @@ -5505,7 +5577,7 @@ N=$((N+1)) NAME=TCP4LOWPORT case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%lowport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with LOWPORT option" if ! eval $NUMCOND; then :; else newport tcp4 # provide free port number in $PORT @@ -5516,13 +5588,12 @@ N=$((N+1)) NAME=TCP4WRAPPERS_ADDR case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip4 libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ha="$td/hosts.allow" hd="$td/hosts.deny" @@ -5536,13 +5607,12 @@ N=$((N+1)) NAME=TCP4WRAPPERS_NAME case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip4 libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ha="$td/hosts.allow" hd="$td/hosts.deny" @@ -5557,13 +5627,12 @@ N=$((N+1)) NAME=TCP6RANGE case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP6-L with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport tcp6 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "TCP6-L:$PORT,reuseaddr,fork,retry=1" "" "range=[::2]/128" "TCP6:[::1]:$PORT" 6 tcp $PORT 0 @@ -5573,13 +5642,12 @@ N=$((N+1)) NAME=TCP6SOURCEPORT case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%sourceport%*|*%listen%|*%fork%**|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%sourceport%*|*%listen%|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP6-L with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport tcp6 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "TCP6-L:$PORT,reuseaddr,fork,retry=1" "" "sp=$PORT" "TCP6:[::1]:$PORT" 6 tcp $PORT 0 @@ -5589,13 +5657,12 @@ N=$((N+1)) NAME=TCP6LOWPORT case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%lowport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP6-L with LOWPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport tcp6 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "TCP6-L:$PORT,reuseaddr,fork,retry=1" "" "lowport" "TCP6:[::1]:$PORT" 6 tcp $PORT 0 @@ -5605,13 +5672,12 @@ N=$((N+1)) NAME=TCP6TCPWRAP case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP6-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6 libwrap && runstcp6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ha="$td/hosts.allow" hd="$td/hosts.deny" @@ -5665,8 +5731,7 @@ TEST="$NAME: security of UDP4-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip4 libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ha="$td/hosts.allow" hd="$td/hosts.deny" @@ -5686,8 +5751,7 @@ TEST="$NAME: security of UDP6-L with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp6 # provide free port number in $PORT #testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr,fork" "" "range=[::2]/128" "UDP6:[::1]:$PORT" 6 udp $PORT 0 @@ -5703,8 +5767,7 @@ TEST="$NAME: security of UDP6-L with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp6 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr" "" "sp=$PORT" "UDP6:[::1]:$PORT" 6 udp $PORT 0 @@ -5719,8 +5782,7 @@ TEST="$NAME: security of UDP6-L with LOWPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp6 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr" "" "lowport" "UDP6:[::1]:$PORT" 6 udp $PORT 0 @@ -5735,8 +5797,7 @@ TEST="$NAME: security of UDP6-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6 libwrap && runsip6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ha="$td/hosts.allow" hd="$td/hosts.deny" @@ -5750,13 +5811,12 @@ N=$((N+1)) NAME=OPENSSLTCP4_RANGE case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of SSL-L over TCP/IPv4 with RANGE option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv newport tcp4 # provide free port number in $PORT @@ -5767,13 +5827,12 @@ N=$((N+1)) NAME=OPENSSLTCP4_SOURCEPORT case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%sourceport%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%sourceport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of SSL-L with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv newport tcp4 # provide free port number in $PORT @@ -5784,13 +5843,12 @@ N=$((N+1)) NAME=OPENSSLTCP4_LOWPORT case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%lowport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of SSL-L with LOWPORT option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv newport tcp4 # provide free port number in $PORT @@ -5801,13 +5859,12 @@ N=$((N+1)) NAME=OPENSSLTCP4_TCPWRAP case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of SSL-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 tcp libwrap openssl); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv ha="$td/hosts.allow" @@ -5822,13 +5879,12 @@ N=$((N+1)) NAME=OPENSSLCERTSERVER case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of SSL-L with client certificate" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv gentestcert testcli @@ -5840,13 +5896,12 @@ N=$((N+1)) NAME=OPENSSLCERTCLIENT case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of SSL with server certificate" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv gentestcert testcli @@ -5859,17 +5914,15 @@ N=$((N+1)) NAME=OPENSSLTCP6_RANGE case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of SSL-L over TCP/IPv6 with RANGE option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert6 testsrv6 newport tcp6 # provide free port number in $PORT @@ -5880,17 +5933,15 @@ N=$((N+1)) NAME=OPENSSLTCP6_SOURCEPORT case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%sourceport%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%sourceport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of SSL-L over TCP/IPv6 with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert6 testsrv6 newport tcp6 # provide free port number in $PORT @@ -5901,17 +5952,15 @@ N=$((N+1)) NAME=OPENSSLTCP6_LOWPORT case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%lowport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of SSL-L over TCP/IPv6 with LOWPORT option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert6 testsrv6 newport tcp6 # provide free port number in $PORT @@ -5922,13 +5971,12 @@ N=$((N+1)) NAME=OPENSSLTCP6_TCPWRAP case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of SSL-L over TCP/IPv6 with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip6 tcp libwrap openssl && runsip6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert6 testsrv6 ha="$td/hosts.allow" @@ -5945,19 +5993,17 @@ N=$((N+1)) # test security with the openssl-commonname option on client side NAME=OPENSSL_CN_CLIENT_SECURITY case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of client openssl-commonname option" # connect using non matching server name/address with commonname # options, this should succeed. Then without this option, should fail if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv gentestcert testcli @@ -5978,12 +6024,10 @@ TEST="$NAME: security of server openssl-commonname option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv gentestcert testcli @@ -5996,21 +6040,18 @@ N=$((N+1)) NAME=OPENSSL_FIPS_SECURITY case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%openssl%*|*%fips%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%openssl%*|*%fips%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: OpenSSL restrictions by FIPS" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testoptions fips >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL/FIPS not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv gentestcert testcli @@ -6026,7 +6067,7 @@ NAME=UNIEXECEOF case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: give exec'd write-only process a chance to flush (-u)" -testod "$N" "$TEST" "" EXEC:"$OD_C" "$opts -u" +testod "$N" "$NAME" "$TEST" "" EXEC:"$OD_C" "$opts -u" esac N=$((N+1)) @@ -6035,7 +6076,7 @@ NAME=REVEXECEOF case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: give exec'd write-only process a chance to flush (-U)" -testod "$N" "$TEST" EXEC:"$OD_C" "-" "$opts -U" +testod "$N" "$NAME" "$TEST" EXEC:"$OD_C" "-" "$opts -U" esac N=$((N+1)) @@ -6050,13 +6091,11 @@ printf "test $F_n $TEST... " $N type=$($FILAN -f . 2>$te |tail -n 1 |awk '{print($2);}') if [ "$type" = "dir" ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi ;; # NUMCOND esac @@ -6085,16 +6124,14 @@ if [ "$type" = "socket" ]; then echo "$SOCAT $opts UNIX-LISTEN:\"$ts\" /dev/null </dev/null 2>\"$te1\"" echo "$FILAN -f "$ts" 2>$te2 |tail -n 1 |awk '{print(\$2);}'" fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$SOCAT $opts UNIX-LISTEN:\"$ts\" /dev/null </dev/null 2>\"$te1\"" >&2 cat "$te1" echo "$FILAN -f "$ts" 2>$te2 |tail -n 1 |awk '{print(\$2);}'" >&2 cat "$te2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi kill $spid 2>/dev/null wait @@ -6143,8 +6180,7 @@ if echo "$da" |diff - "$tf"> "$tdiff"; then echo " $TRACE $SOCAT $opts -lpsocat1 PTY,$PTYTYPE,pty-wait-slave,link=\"$tp\" UNIX-LISTEN:\"$ts\"" >&2 echo " $TRACE $SOCAT -lpsocat3 $opts - file:\"$tp\",$PTYOPTS2" >&2 fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "${YELLOW}FAILED${NORMAL}\n" cat "$te1" @@ -6152,8 +6188,7 @@ else cat "$te3" cat "$te4" cat "$tdiff" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant fi set +vx } @@ -6166,12 +6201,10 @@ TEST="$NAME: test if master pty ($PTYTYPE) waits for slave connection" if ! eval $NUMCOND; then :; else if ! feat=$(testfeats pty); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions "$PTYTYPE" pty-wait-slave); then $PRINTF "test $F_n $TEST... ${YELLOW}option $(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else testptywaitslave "$N" "$TEST" "$PTYTYPE" "$opts" fi @@ -6187,12 +6220,10 @@ TEST="$NAME: test if master pty ($PTYTYPE) waits for slave connection" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats pty); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions "$PTYTYPE" pty-wait-slave); then $PRINTF "test $F_n $TEST... ${YELLOW}option $(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else testptywaitslave "$N" "$TEST" "$PTYTYPE" "$opts" fi ;; # NUMCOND, feats @@ -6208,12 +6239,10 @@ TEST="$NAME: test the connect-timeout option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions connect-timeout); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else # We need a hanging connection attempt, guess an address for this case "$UNAME" in @@ -6235,8 +6264,7 @@ if ! kill $pid1 2>"$tk1"; then $PRINTF "${YELLOW}does not hang${NORMAL}\n" echo "$CMD" >&2 cat "$te1" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else # Second, set connect-timeout and see if socat exits before kill CMD="$TRACE $SOCAT $opts - TCP:$HANGIP:1,connect-timeout=$(reltime 1)" @@ -6247,15 +6275,13 @@ if kill $pid2 2>"$tk2"; then $PRINTF "$FAILED (\n" echo "$CMD" >&2 cat "$te2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD" >&2 fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi wait @@ -6296,8 +6322,7 @@ if [ $rc2 -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED (diff)\n" echo "$CMD1 &" @@ -6306,13 +6331,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}2" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi ;; esac fi # NUMCOND @@ -6326,8 +6349,7 @@ TEST="$NAME: openssl listen with DSA certificate" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else SRVCERT=testsrvdsa gentestdsacert $SRVCERT @@ -6350,13 +6372,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat ${te}1 ${te}2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -6391,8 +6411,7 @@ TEST="$NAME: exit status when dying on SIG$signam" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats pty); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr a-z A-Z) not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else SIG="$(signum $signam)" te="$td/test$N.stderr" @@ -6418,14 +6437,12 @@ sleep 1; kill -INT $(cat $tp) wait if [ "$stat" -eq $((128+$SIG)) ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi wait fi ;; # NUMCOND, feats @@ -6442,8 +6459,7 @@ TEST="$NAME: restrict reading from file with bytes option" if ! eval $NUMCOND; then :; elif false; then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tr="$td/test$N.ref" ti="$td/test$N.in" @@ -6467,13 +6483,11 @@ if ! diff "$tr" "$to" >"$tdiff" 2>&1; then echo "$CMD" cat "$te" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -6487,20 +6501,16 @@ TEST="$NAME: UDP socket rebinds after first connection" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO IP4 UDP PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO UDP4-CONNECT UDP4-LISTEN PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions bind so-reuseaddr fork) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -6525,8 +6535,7 @@ if [ $? -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then kill "$pids" 2>/dev/null $PRINTF "$NO_RESULT (first conn failed); diff:\n" @@ -6535,8 +6544,7 @@ elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then echo "$CMD1" cat "${te}1" >&2 cat "$tdiff" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else relsleep 2 # UDP-LISTEN sleeps 1s echo "$da2" |eval "$CMD1" >"${tf}2" 2>"${te}2" @@ -6547,8 +6555,7 @@ if [ $rc -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da2" |diff - "${tf}2" >"$tdiff"; then $PRINTF "$FAILED: diff\n" echo "$CMD0 &" @@ -6557,16 +6564,14 @@ elif ! echo "$da2" |diff - "${tf}2" >"$tdiff"; then cat "${te}1" >&2 echo "diff:" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # !( $? -ne 0) fi # !(rc -ne 0) wait @@ -6593,11 +6598,10 @@ TEST="$NAME: $PROTOV listen handles 2 concurrent connections" if ! eval $NUMCOND; then :; #elif ! feat=$(testfeats $PROTOV); then # $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$PROTOV" |tr a-z A-Z) not available${NORMAL}\n" $N -# numCANT=$((numCANT+1)) +# cant elif ! runs$protov >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$PROTOV not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ts="$td/test$N.sock" tref="$td/test$N.ref" @@ -6613,7 +6617,7 @@ case "$MAJADDR" in tca="$ts" waitproto="file" waitfor="$ts" ;; -esac +esac case "$MINADDR" in "PORT") newport $protov # provide free port number in $PORT @@ -6621,7 +6625,7 @@ case "$MINADDR" in tca="$MAJADDR:$PORT" waitproto="${protov}port" waitfor="$PORT" ;; -esac +esac #set -xv echo -e "$da1a\n$da2\n$da1b" >"$tref" # establish a listening and forking listen socket in background @@ -6649,8 +6653,7 @@ if ! diff -u "$tref" "$tf" >"$tdiff"; then echo "$CMD1" cat "${te}2" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -6659,8 +6662,7 @@ else if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # !(rc -ne 0) wait fi ;; # NUMCOND, feats @@ -6702,18 +6704,15 @@ if [ $? -ne 0 ]; then echo "$SRV &" echo "$CLI" cat "${te}s" "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then kill "$pids" 2>/dev/null $PRINTF "$FAILED; diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # !(rc -ne 0) wait fi ;; # NUMCOND @@ -6752,8 +6751,7 @@ if [ $rc -ne 0 ]; then cat "${te}s" echo "$CLI" cat "${te}1" "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then kill "$pids" 2>/dev/null $PRINTF "$FAILED:\n" @@ -6762,12 +6760,10 @@ elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then echo "$CLI" cat "${te}1" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # !(rc -ne 0) fi ;; # NUMCOND esac @@ -6782,7 +6778,7 @@ TEST="$NAME: simple echo via exec of cat with pipes,stderr" # this test is known to fail when logging is enabled with OPTS/opts env var. SAVE_opts="$opts" opts="$(echo "$opts" |sed 's/-dd*//g')" -testecho "$N" "$TEST" "" "EXEC:$CAT,pipes,stderr" "$opts" +testecho "$N" "$NAME" "$TEST" "" "EXEC:$CAT,pipes,stderr" "$opts" opts="$SAVE_opts" esac N=$((N+1)) @@ -6799,7 +6795,7 @@ case "$opts" in *-d*) opts="$opts -d" ;; *) opts="-d -d" ;; esac -testecho "$N" "$TEST" "" "exec:$CAT,pipes,stderr" "$opts" +testecho "$N" "$NAME" "$TEST" "" "exec:$CAT,pipes,stderr" "$opts" opts="$SAVE_opts" esac N=$((N+1)) @@ -6810,7 +6806,7 @@ NAME=SIMPLEPARSE case "$TESTS" in *%$N%*|*%functions%*|*%PARSE%*|*%$NAME%*) TEST="$NAME: invoke socat from socat" -testecho "$N" "$TEST" "" exec:"$SOCAT - exec\:$CAT,pipes" "$opts" "$val_t" +testecho "$N" "$NAME" "$TEST" "" exec:"$SOCAT - exec\:$CAT,pipes" "$opts" "$val_t" esac N=$((N+1)) @@ -6835,20 +6831,17 @@ if [ "$rc" -ne 0 ]; then $PRINTF "$FAILED:\n" echo "$TRACE $SOCAT" -u "exec:echo $da" - cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif [ -s "$tdiff" ]; then $PRINTF "$FAILED:\n" echo diff: cat "$tdiff" if [ -n "$debug" ]; then cat $te; fi - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -6858,7 +6851,7 @@ NAME=NESTEDSOCATEXEC case "$TESTS" in *%parse%*|*%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: does lexical analysis work sensibly (exec)" -testecho "$N" "$TEST" "" "exec:'$SOCAT - exec:$CAT,pipes'" "$opts" 1 +testecho "$N" "$NAME" "$TEST" "" "exec:'$SOCAT - exec:$CAT,pipes'" "$opts" 1 esac N=$((N+1)) @@ -6866,7 +6859,7 @@ NAME=NESTEDSOCATSYSTEM case "$TESTS" in *%parse%*|*%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: does lexical analysis work sensibly (system)" -testecho "$N" "$TEST" "" "system:\"$SOCAT - exec:$CAT,pipes\"" "$opts" 1 +testecho "$N" "$NAME" "$TEST" "" "system:\"$SOCAT - exec:$CAT,pipes\"" "$opts" 1 esac N=$((N+1)) @@ -6878,12 +6871,10 @@ TEST="$NAME: TCP4 mapped into TCP6 address space" if ! eval $NUMCOND; then :; elif true; then $PRINTF "test $F_n $TEST... ${YELLOW}Feature removed${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -6904,18 +6895,15 @@ if [ $? -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null; wait fi ;; # NUMCOND, feats @@ -6955,8 +6943,7 @@ if [ "$rc2" -ne 0 ]; then cat "${te}1" echo "$CMD2" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" @@ -6964,13 +6951,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" echo "$CMD2" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -6985,8 +6970,7 @@ TEST="$NAME: UDP/IPv6 datagram" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -7009,18 +6993,15 @@ if [ $? -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat ${te}1 ${te}2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -7034,8 +7015,7 @@ TEST="$NAME: raw IPv4 datagram" if ! eval $NUMCOND; then :; elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -7061,18 +7041,15 @@ if [ $rc2 -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # root, NUMCOND esac @@ -7087,12 +7064,10 @@ TEST="$NAME: raw IPv6 datagram by self addressing" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip6 rawip && runsip6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -7114,18 +7089,15 @@ if [ $? -ne 0 ]; then # cat "${te}1" echo "$CMD2" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "$te"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # root, NUMCOND esac @@ -7159,8 +7131,7 @@ if [ $rc2 -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED (diff)\n" echo "$CMD1 &" @@ -7169,16 +7140,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}2" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -7215,8 +7184,7 @@ if [ "$rc2" -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" @@ -7224,13 +7192,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -7245,8 +7211,7 @@ TEST="$NAME: UDP/IPv6 receive" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -7272,18 +7237,15 @@ if [ "$rc2" -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -7297,8 +7259,7 @@ TEST="$NAME: raw IPv4 receive" if ! eval $NUMCOND; then :; elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -7324,18 +7285,15 @@ if [ "$rc2" -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, root esac @@ -7349,12 +7307,10 @@ TEST="$NAME: raw IPv6 receive" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip6 rawip && runsip6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -7379,18 +7335,15 @@ if [ "$rc2" -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, root esac @@ -7424,18 +7377,15 @@ if [ "$rc2" -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -7450,8 +7400,7 @@ TEST="$NAME: security of UDP4-RECVFROM with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp4 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr" "" "sp=$PORT" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0 @@ -7466,8 +7415,7 @@ TEST="$NAME: security of UDP4-RECVFROM with LOWPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp4 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr" "" "lowport" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0 @@ -7494,8 +7442,7 @@ TEST="$NAME: security of UDP4-RECVFROM with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 udp libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ha="$td/hosts.allow" hd="$td/hosts.deny" @@ -7516,8 +7463,7 @@ TEST="$NAME: security of UDP4-RECV with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp4; PORT1=$PORT newport udp4; PORT2=$PORT @@ -7536,8 +7482,7 @@ TEST="$NAME: security of UDP4-RECV with LOWPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp4; PORT1=$PORT newport udp4; PORT2=$PORT @@ -7555,8 +7500,7 @@ TEST="$NAME: security of UDP4-RECV with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp4; PORT1=$PORT newport udp4; PORT2=$PORT @@ -7574,8 +7518,7 @@ TEST="$NAME: security of UDP4-RECV with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip4 libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp4; PORT1=$PORT newport udp4; PORT2=$PORT @@ -7598,8 +7541,7 @@ TEST="$NAME: security of UDP6-RECVFROM with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp6 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr" "" "sp=$PORT" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0 @@ -7614,8 +7556,7 @@ TEST="$NAME: security of UDP6-RECVFROM with LOWPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp6 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr" "" "lowport" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0 @@ -7630,8 +7571,7 @@ TEST="$NAME: security of UDP6-RECVFROM with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp6 # provide free port number in $PORT #testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr,fork" "" "range=[::2]/128" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0 @@ -7647,8 +7587,7 @@ TEST="$NAME: security of UDP6-RECVFROM with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6 libwrap && runsip6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ha="$td/hosts.allow" hd="$td/hosts.deny" @@ -7668,8 +7607,7 @@ TEST="$NAME: security of UDP6-RECV with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp6; PORT1=$PORT newport udp6; PORT2=$PORT @@ -7688,8 +7626,7 @@ TEST="$NAME: security of UDP6-RECV with LOWPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp6; PORT1=$PORT newport udp6; PORT2=$PORT @@ -7707,8 +7644,7 @@ TEST="$NAME: security of UDP6-RECV with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp6; PORT1=$PORT newport udp6; PORT2=$PORT @@ -7726,8 +7662,7 @@ TEST="$NAME: security of UDP6-RECV with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6 libwrap && runsip6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ha="$td/hosts.allow" hd="$td/hosts.deny" @@ -7750,12 +7685,10 @@ TEST="$NAME: security of IP4-RECVFROM with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp4 # provide free port number in $PORT #testserversec "$N" "$TEST" "$opts" "IP4-RECVFROM:$IPPROTO,reuseaddr,fork" "" "range=$SECONDADDR/32" "IP4-SENDTO:127.0.0.1:$IPPROTO" 4 ip $IPPROTO 0 @@ -7772,12 +7705,10 @@ TEST="$NAME: security of IP4-RECVFROM with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 rawip libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ha="$td/hosts.allow" hd="$td/hosts.deny" @@ -7800,12 +7731,10 @@ TEST="$NAME: security of IP4-RECV with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else IPPROTO1=$IPPROTO; #IPPROTO=$((IPPROTO+1)) IPPROTO2=$((IPPROTO+1)) @@ -7826,12 +7755,10 @@ TEST="$NAME: security of IP4-RECV with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 rawip libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else IPPROTO1=$IPPROTO; #IPPROTO=$((IPPROTO+1)) IPPROTO2=$((IPPROTO+1)) @@ -7855,12 +7782,10 @@ TEST="$NAME: security of IP6-RECVFROM with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip6 rawip && runsip6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp6 # provide free port number in $PORT #testserversec "$N" "$TEST" "$opts" "IP6-RECVFROM:$IPPROTO,reuseaddr,fork" "" "range=[::2]/128" "IP6-SENDTO:[::1]:$IPPROTO" 6 ip $IPPROTO 0 @@ -7877,12 +7802,10 @@ TEST="$NAME: security of IP6-RECVFROM with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip6 rawip libwrap && runsip6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ha="$td/hosts.allow" hd="$td/hosts.deny" @@ -7904,12 +7827,10 @@ TEST="$NAME: security of IP6-RECV with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip6 rawip) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}raw IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else IPPROTO1=$IPPROTO; #IPPROTO=$((IPPROTO+1)) IPPROTO2=$((IPPROTO+1)) @@ -7928,12 +7849,10 @@ TEST="$NAME: security of IP6-RECV with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip6 rawip libwrap && runsip6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else IPPROTO1=$IPPROTO; #IPPROTO=$((IPPROTO+1)) IPPROTO2=$((IPPROTO+1)) @@ -7961,8 +7880,7 @@ TEST="$NAME: option O_NOATIME on file" if ! eval $NUMCOND; then :; elif ! testoptions o-noatime >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}o-noatime not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.file" te="$td/test$N.stderr" @@ -7982,8 +7900,7 @@ if [ $? -ne 0 ]; then # command failed $PRINTF "${FAILED}:\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else # check which file has a later atime stamp if [ $(ls -ltu "${tf}1" "${tf}2" |head -1 |sed 's/.* //') != "${tf}2" ]; @@ -7991,13 +7908,11 @@ then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "$te"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # wrong time stamps fi # command ok fi ;; # NUMCOND, feats @@ -8015,8 +7930,7 @@ TEST="$NAME: option O_NOATIME on file descriptor" if ! eval $NUMCOND; then :; elif ! testoptions o-noatime >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}o-noatime not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.file" te="$td/test$N.stderr" @@ -8038,8 +7952,7 @@ if [ $rc -ne 0 ]; then # command failed $PRINTF "${FAILED} (rc=$rc):\n" echo "$CMD" cat "$te" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else # check which file has a later atime stamp if [ $(ls -ltu "${tf}1" "${tf}2" |head -1 |sed 's/.* //') != "${tf}2" ]; @@ -8047,14 +7960,12 @@ then $PRINTF "$FAILED (bad order):\n" echo "$CMD" >&2 cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD"; fi if [ "$DEBUG" ]; then cat "${te}" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # wrong time stamps fi # command ok fi ;; # NUMCOND, feats @@ -8072,8 +7983,7 @@ TEST="$NAME: extended file system options using fs noatime option" if ! eval $NUMCOND; then :; elif ! testoptions fs-noatime >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}fs-noatime not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ts="$td/test$N.socket" tf="$td/test$N.file" @@ -8088,8 +7998,7 @@ CMD="$TRACE $SOCAT $opts -u /dev/null create:\"${tf}1\",fs-noatime" $CMD0 2>"${te}0" if [ $? -ne 0 ]; then $PRINTF "${YELLOW} cannot test${NORMAL}\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else # generate a file with noatime, len >= 1 $CMD 2>"$te" @@ -8097,8 +8006,7 @@ if [ $? -ne 0 ]; then # command failed $PRINTF "${YELLOW}impotent file system?${NORMAL}\n" echo "$CMD" cat "$te" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else sleep 1 # generate a reference file @@ -8113,13 +8021,11 @@ then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "$te"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # not impotent fi # can test @@ -8135,8 +8041,7 @@ TEST="$NAME: option cool-write" if ! eval $NUMCOND; then :; elif ! testoptions cool-write >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}option cool-write not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else #set -vx ti="$td/test$N.pipe" @@ -8158,13 +8063,11 @@ if [ $rc -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD &" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "$te"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -8186,8 +8089,7 @@ TEST="$NAME: option cool-write on bidirectional stdio" if ! eval $NUMCOND; then :; elif ! testoptions cool-write >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}option cool-write not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else #set -vx ti="$td/test$N.pipe" @@ -8211,13 +8113,11 @@ if [ $rc -ne 0 ]; then cat "${te}1" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "$te"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -8264,8 +8164,7 @@ if [ $rc2a -ne 0 -o $rc2b -ne 0 ]; then cat "${te}2a" >&2 echo "$CMD2" cat "${te}2b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! $ECHO "$da2a\n$da2b" |diff - "${tf}0" >"$tdiff"; then $PRINTF "$FAILED (diff)\n" echo "$CMD0 &" @@ -8277,8 +8176,7 @@ elif ! $ECHO "$da2a\n$da2b" |diff - "${tf}0" >"$tdiff"; then echo "$CMD2" cat "${te}2b" >&2 cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -8289,8 +8187,7 @@ else if [ "$DEBUG" ]; then cat "${te}2a" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -8325,19 +8222,16 @@ if [ $? -ne 0 ]; then echo "$CMD1 &" echo "$CMD2" cat "${te}1a" "${te}1b" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! $ECHO "$da1a\n$da1b" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" cat "${te}1a" "${te}1b" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1a" "${te}1b" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -8371,14 +8265,12 @@ PTY=$(grep "N PTY is " $te |sed 's/.*N PTY is //') rc=$(cat "$td/test$N.rc0") if [ "$rc" = 0 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD" cat "${te}" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -8422,8 +8314,7 @@ if [ $rc1 != 0 -o $rc2 != 0 ]; then cat "${te}1" >&2 echo "$CMD1" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif echo "$da" |diff - "${tf}" >"$tdiff"; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -8432,8 +8323,7 @@ elif echo "$da" |diff - "${tf}" >"$tdiff"; then if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED (diff)\n" echo "$CMD0 &" @@ -8444,8 +8334,7 @@ else cat "${te}2" >&2 echo "// diff:" >&2 cat "${tdiff}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -8462,8 +8351,7 @@ TEST="$NAME: UDP6-LISTEN with bind" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -8485,18 +8373,15 @@ if [ $rc2 -ne 0 ]; then echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -8512,8 +8397,7 @@ TEST="$NAME: use of multiple tcpwrapper enabling options" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip4 libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -8537,18 +8421,15 @@ if [ $rc2 -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -8564,8 +8445,7 @@ TEST="$NAME: specification of TCP6 address in hosts.allow" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6 libwrap && runsip6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -8591,18 +8471,15 @@ if [ $rc2 -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -8616,8 +8493,7 @@ TEST="$NAME: UDP/IPv4 broadcast" if ! eval $NUMCOND; then :; elif [ -z "$BCADDR" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}dont know a broadcast address${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -8644,13 +8520,11 @@ if [ "$rc2" -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$tut" ]; then @@ -8658,8 +8532,7 @@ else echo "$CMD2" fi if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -8676,12 +8549,10 @@ TEST="$NAME: raw IPv4 broadcast" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}raw IP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ -z "$BCADDR" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}dont know a broadcast address${NORMAL}\n" $N else @@ -8714,8 +8585,7 @@ if [ "$rc2" -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" | sed 's/XXXX/YYYY/'|diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED (diff)\n" echo "$CMD1 &" @@ -8724,16 +8594,14 @@ elif ! echo "$da" | sed 's/XXXX/YYYY/'|diff - "$tf" >"$tdiff"; then cat "${te}2" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -8763,16 +8631,13 @@ TEST="$NAME: UDP/IPv4 multicast, send only" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 udp) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs UDP4-RECV UDP4-SENDTO); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions ip-add-membership bind) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -8797,8 +8662,7 @@ if [ "$rc2" -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD1 &" @@ -8806,16 +8670,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD2" cat "${te}2" >&2 cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -8828,12 +8690,10 @@ TEST="$NAME: IPv4 multicast" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -8860,18 +8720,15 @@ if [ "$rc2" -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -8888,24 +8745,19 @@ TEST="$NAME: UDP/IPv6 multicast" if ! eval $NUMCOND; then :; elif ! f=$(testfeats ip6 udp); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $f not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs - STDIO UDP6-RECV UDP6-SENDTO); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions ipv6-join-group) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 does not work on $HOSTNAME${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! echo |$SOCAT -u -t 0.1 - UDP6-SENDTO:[ff02::1]:12002 >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 multicasting does not work${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -8931,14 +8783,11 @@ if [ "$rc2" -ne 0 ]; then cat "${te}1" echo "$CMD2" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then # if ! [ "$UNAME" = Linux ] || ! [[ $(uname -r) =~ ^2\.* ]] || ! [[ ^3\.* ]] || ! [[ ^4\.[0-4]\.* ]]; then # $PRINTF "${YELLOW}works only on Linux up to about 4.4${NORMAL}\n" $N -# numCANT=$((numCANT+1)) -# listCANT="$listCANT $N" +# cant # else $PRINTF "$FAILED\n" echo "$CMD1 &" @@ -8946,8 +8795,7 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD2" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed # fi else $PRINTF "$OK\n" @@ -8955,8 +8803,7 @@ else if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -8993,8 +8840,7 @@ if [ "$rc2" -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD1 &" @@ -9003,16 +8849,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}2" >&2 echo diff: >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -9025,12 +8869,10 @@ TEST="$NAME: IPv4 multicast, with reply" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -9056,13 +8898,11 @@ if [ "$rc2" -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$tut" ]; then @@ -9070,8 +8910,7 @@ else echo "$CMD2" fi if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -9089,12 +8928,10 @@ TEST="$NAME: reading data sent through tun interface" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 tun) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -9119,21 +8956,18 @@ if [ $? -ne 0 ]; then echo "$CMD &" echo "$CMD1" cat "${te}" "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD &" echo "$CMD1" cat "$tdiff" cat "${te}" "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}" "${te}1"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -9151,12 +8985,10 @@ TEST="$NAME: pass data through tun interface using INTERFACE" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 tun interface) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -9183,8 +9015,7 @@ if [ "$rc1" -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED (diff)\n" echo "$CMD0 &" @@ -9193,16 +9024,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" >&2 echo "// diff:" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -9216,8 +9045,7 @@ TEST="$NAME: abstract UNIX stream socket, listen and connect" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats abstract-unixsocket); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ts="$td/test$N.socket" tf="$td/test$N.stdout" @@ -9242,8 +9070,7 @@ if [ $? -ne 0 ]; then cat "${te}s" echo "$CMD" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then kill "$pids" 2>/dev/null $PRINTF "$FAILED:\n" @@ -9252,13 +9079,11 @@ elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then echo "$CMD" cat "${te}1" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # !(rc -ne 0) wait fi ;; # NUMCOND, feats @@ -9273,8 +9098,7 @@ TEST="$NAME: abstract UNIX datagram" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats abstract-unixsocket); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -9299,8 +9123,7 @@ if [ $rc2 -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD1 &" @@ -9308,16 +9131,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD2" cat "${te}2" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -9331,8 +9152,7 @@ TEST="$NAME: abstract UNIX datagram receive" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats abstract-unixsocket); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ts="$td/test$N.socket" tf="$td/test$N.stdout" @@ -9358,8 +9178,7 @@ if [ "$rc2" -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD1 &" @@ -9367,16 +9186,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD2" cat "${te}2" >&2 cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -9395,8 +9212,7 @@ TEST="$NAME: abstract bind" if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -9412,21 +9228,18 @@ if [ $rc1 -ne 0 ]; then echo "$CMD1" echo "rc=$rc1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif echo "$da" |diff -q - $tf; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD1" >&2 cat "${te}1" >&2 echo "$da" |diff - "$tf" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -9453,8 +9266,7 @@ TEST="$NAME: socat handles data buffered by openssl" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats openssl) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.out" te="$td/test$N.err" @@ -9479,13 +9291,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD2" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi wait fi # NUMCOND, featsesac @@ -9495,7 +9305,7 @@ N=$((N+1)) # test: there is a bug with the readbytes option: when the socket delivered -# exacly that many bytes as specified with readbytes and the stays idle (no +# exactly that many bytes as specified with readbytes and the stays idle (no # more data, no EOF), socat waits for more data instead of generating EOF on # this in put stream. NAME=READBYTES_EOF @@ -9509,8 +9319,7 @@ TEST="$NAME: trigger EOF after that many bytes, even when socket idle" if ! eval $NUMCOND; then :; elif false; then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tr="$td/test$N.ref" ti="$td/test$N.in" @@ -9524,13 +9333,11 @@ printf "test $F_n $TEST... " $N if test -s "$to"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -9542,7 +9349,7 @@ N=$((N+1)) NAME=EXECPTYKILL case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%exec%*|*%pty%*|*%listen%*|*%unix%*|*%fork%*|*%$NAME%*) -TEST="$NAME: exec:...,pty explicitely kills sub process" +TEST="$NAME: exec:...,pty explicitly kills sub process" # we want to check if the exec'd sub process is killed in time # for this we have a shell script that generates a file after two seconds; # it should be killed after one second, so if the file was generated the test @@ -9574,18 +9381,15 @@ if [ $? -ne 0 ]; then echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif [ -f "$tda" ]; then $PRINTF "$FAILED\n" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -9625,18 +9429,15 @@ if [ $? -ne 0 ]; then cat "${te}1" echo "$CMD2" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid1 2>/dev/null wait @@ -9670,15 +9471,13 @@ TEST="$NAME: more than FOPEN_MAX FDs in use" if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else REDIR= #set -vx if [ -z "$FOPEN_MAX" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}could not determine FOPEN_MAX${NORMAL}\n" "$N" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else if [ $FOPEN_MAX -lt 270 ]; then OPEN_FILES=$FOPEN_MAX # more than the highest FOPEN_MAX @@ -9691,9 +9490,9 @@ i=3; while [ "$i" -lt "$OPEN_FILES" ]; do i=$((i+1)) done #echo "$REDIR" -#testecho "$N" "$TEST" "" "pipe" "$opts -T 3" "" 1 +#testecho "$N" "$NAME" "$TEST" "" "pipe" "$opts -T 3" "" 1 #set -vx -eval testecho "\"$N\"" "\"$TEST\"" "\"\"" "pipe" "\"$opts -T $((2*SECONDs))\"" 1 $REDIR +eval testecho "\"$N\"" "\"$NAME\"" "\"$TEST\"" "\"\"" "pipe" "\"$opts -T $((2*SECONDs))\"" 1 $REDIR #set +vx fi # could determine FOPEN_MAX fi ;; # NUMCOND @@ -9732,24 +9531,20 @@ l="$(childprocess $pid1)" kill $pid1 2>/dev/null; wait if [ $rc2 -ne 0 ]; then $PRINTF "$NO_RESULT (client failed)\n" # already handled in test UDP4STREAM - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$NO_RESULT (diff failed)\n" # already handled in test UDP4STREAM - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif $(isdefunct "$l"); then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -9792,16 +9587,14 @@ if [ $rc2 -ne 0 ]; then if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$NO_RESULT\n" # already handled in test UDP4DGRAM if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif $(isdefunct "$l"); then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" @@ -9809,16 +9602,14 @@ elif $(isdefunct "$l"); then echo "$CMD2" cat "${te}2" >&2 cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -9838,8 +9629,7 @@ TEST="$NAME: raw IPv4 receive with bind" if ! eval $NUMCOND; then :; elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -9865,18 +9655,15 @@ if [ "$rc2" -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, root esac @@ -9915,8 +9702,7 @@ rc2b=$? kill $pid1 2>/dev/null; wait if [ $rc2b -ne 0 ]; then $PRINTF "$NO_RESULT\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! echo "$da2b" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" >&2 @@ -9924,13 +9710,11 @@ elif ! echo "$da2b" |diff - "$tf" >"$tdiff"; then echo "$CMD2" >&2 cat "${te}2b" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -9957,20 +9741,17 @@ echo "$da" |diff - "$tf" >"$tdiff" if [ "$rc" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif [ -s "$tdiff" ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo diff: cat "$tdiff" if [ -n "$debug" ]; then cat $te; fi - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10012,24 +9793,20 @@ fi kill $pid1 2>/dev/null; wait if [ $rc1 -ne 0 ]; then $PRINTF "$NO_RESULT\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $nsocks -eq 0 ]; then $PRINTF "$NO_RESULT\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $nsocks -ne 1 ]; then $PRINTF "$FAILED ($nsocks listening sockets)\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10060,19 +9837,16 @@ if [ $rc0 != 0 ]; then echo "$CMD1" cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif echo "$da" |diff - "$tf" >/dev/null; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi ;; # NUMCOND esac @@ -10098,18 +9872,15 @@ if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10138,13 +9909,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10169,20 +9938,16 @@ if ! eval $NUMCOND; then :; #elif [[ "$PF" == "#*" ]]; then : elif [ "$ROOT" = root -a $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testfeats ${KEYW%[46]} IP${KEYW##*[A-Z]}); then $PRINTF "test $F_n $TEST... ${YELLOW}$KEYW not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runs${proto} >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$KEYW not available on host${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testoptions $SCM_RECV >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}option $SCM_RECV not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -10238,8 +10003,7 @@ if [ "$rc1" -ne 0 ]; then echo "$CMD1" grep " $LEVELS " "${te}0" grep " $LEVELS " "${te}1" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=" ${te}0 >/dev/null; then $PRINTF "$FAILED\n" echo "variable $SCM_TYPE: $SCM_NAME not set" @@ -10247,8 +10011,7 @@ elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=" ${te}0 >/dev/null; then echo "$CMD1" grep " $LEVELS " "${te}0" grep " $LEVELS " "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=$SCM_VALUE\$" ${te}0 >/dev/null; then $PRINTF "$FAILED\n" badval="$(grep "ancillary message: $SCM_TYPE: $SCM_NAME" ${te}0 |sed 's/.*=//g')" @@ -10257,21 +10020,18 @@ elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=$SCM_VALUE\$" ${te}0 >/dev/ echo "$CMD1" grep " $LEVELS " "${te}0" grep " $LEVELS " "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then grep " $LEVELS " "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "echo XYZ |$CMD1"; fi if [ "$DEBUG" ]; then grep " $LEVELS " "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi else # option is not supported $PRINTF "${YELLOW}$SCM_RECV not available${NORMAL}\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant fi # option is not supported fi # NUMCOND, root, feats ;; @@ -10330,12 +10090,10 @@ TEST="$NAME: $KEYW-LISTEN sets environment variables with socket addresses" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats $FEAT); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr a-z A-Z) not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runs${protov} >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -10373,8 +10131,7 @@ if [ $rc1 != 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ "$(grep SOCAT_SOCKADDR "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g")" = "$TEST_SOCKADDR" -a \ "$(grep SOCAT_PEERADDR "${tf}" |sed -e 's/^[^=]*=//' -e "s/[\"']//g")" = "$TEST_PEERADDR" -a \ \( "$PORTMETHOD" = ',' -o "$(grep SOCAT_SOCKPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$TEST_SOCKPORT" \) -a \ @@ -10387,8 +10144,7 @@ elif [ "$(grep SOCAT_SOCKADDR "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g" echo "$CMD1" cat "${te}1" fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -10397,8 +10153,7 @@ else cat "${te}1" echo -e "SOCAT_SOCKADDR=$TEST_SOCKADDR\nSOCAT_PEERADDR=$TEST_PEERADDR\nSOCAT_SOCKPORT=$TEST_SOCKPORT\nSOCAT_PEERPORT=$TEST_PEERPORT" | diff - "${tf}" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND, feats ;; @@ -10437,12 +10192,10 @@ TEST="$NAME: $KEYW ancillary message sets env SOCAT_$SCM_ENVNAME" if ! eval $NUMCOND; then :; elif [ "$ROOT" = root -a $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ "$PF" = "IP6" ] && ( ! feat=$(testfeats ip6) || ! runsip6 ) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -10494,8 +10247,7 @@ if [ "$rc1" -ne 0 ]; then echo "$CMD1" cat "${te}0" cat "${te}1" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant #elif ! $GREP_E "^export SOCAT_$SCM_ENVNAME=[\"']?$SCM_VALUE[\"']?\$" ${tf} >/dev/null; then #elif ! eval echo "$TRACE $SOCAT_\$SCM_VALUE" |diff - "${tf}" >/dev/null; then elif ! expr "$(cat "$tf")" : "$SCM_VALUE\$" >/dev/null; then @@ -10505,21 +10257,18 @@ elif ! expr "$(cat "$tf")" : "$SCM_VALUE\$" >/dev/null; then echo "$CMD1" cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "{ echo XYZ; sleep 0.1; } |$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi else # option is not supported $PRINTF "${YELLOW}$SCM_RECV not available${NORMAL}\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant fi # option is not supported fi ;; # NUMCOND, feats esac @@ -10587,8 +10336,7 @@ if [ "$rc1" -ne 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" @@ -10596,13 +10344,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -10618,8 +10364,7 @@ TEST="$NAME: socket connect with TCP/IPv6" if ! eval $NUMCOND; then :; elif ! testfeats tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else # start a TCP6-LISTEN process that echoes data, and send test data using # SOCKET-CONNECT, selecting TCP/IPv6. The sent data should be returned. @@ -10648,8 +10393,7 @@ if [ "$rc1" -ne 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" @@ -10657,13 +10401,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10698,8 +10440,7 @@ if [ "$rc1" -ne 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" @@ -10707,13 +10448,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10754,8 +10493,7 @@ if [ "$rc1" -ne 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" @@ -10763,13 +10501,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10808,8 +10544,7 @@ if [ "$rc1" -ne 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" @@ -10817,13 +10552,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10863,8 +10596,7 @@ if [ "$rc1" -ne 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" @@ -10872,13 +10604,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10920,8 +10650,7 @@ if [ "$rc1" -ne 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" @@ -10929,13 +10658,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10976,8 +10703,7 @@ if [ "$rc1" -ne 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" @@ -10985,13 +10711,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10999,14 +10723,13 @@ N=$((N+1)) NAME=SOCKETRANGEMASK case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%generic%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%socket%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%generic%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%socket%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of generic socket-listen with RANGE option" if ! eval $NUMCOND; then :; elif [ -z "$SECONDADDR" ]; then # we need access to more loopback addresses $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport tcp4; ts1p=$(printf "%04x" $PORT); testserversec "$N" "$TEST" "$opts" "SOCKET-LISTEN:2:6:x${ts1p}x00000000x0000000000000000,$REUSEADDR,fork,retry=1" "" "range=x0000x7f000000:x0000xffffffff" "SOCKET-CONNECT:2:6:x${ts1p}x${SECONDADDRHEX}x0000000000000000" 4 tcp $PORT 0 @@ -11030,8 +10753,7 @@ if ! eval $NUMCOND; then :; elif [ -z "$TIOCEXCL" ]; then # we use the numeric value of TIOCEXL which is system dependent $PRINTF "test $F_n $TEST... ${YELLOW}no value of TIOCEXCL${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tp="$td/test$N.pty" tf="$td/test$N.stdout" @@ -11056,21 +10778,18 @@ if ! echo "$da" |diff - "$tf" >/dev/null; then echo "$CMD0 &" echo "$CMD1" echo "$da" |diff - "$tf" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $rc2 -eq 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" echo "$CMD1" echo "$CMD2" cat "${te}0" "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND, TIOCEXCL ;; @@ -11095,8 +10814,7 @@ if ! eval $NUMCOND; then :; elif [ -z "$TCP_MAXSEG" ]; then # we use the numeric value of TCP_MAXSEG which might be system dependent $PRINTF "test $F_n $TEST... ${YELLOW}value of TCPMAXSEG not known${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -11123,29 +10841,25 @@ if ! echo "$da" |diff - "${tf}1" >"$tdiff"; then echo "$CMD1" cat ${te}1 cat "$tdiff" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $rc1 -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" cat ${te}0 echo "$CMD1" cat ${te}1 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif [ $rc2 -eq 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" cat ${te}0 echo "$CMD2" cat ${te}2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -11174,8 +10888,7 @@ if ! eval $NUMCOND; then :; elif [ -z "$SO_REUSEADDR" ]; then # we use the numeric value of SO_REUSEADDR which might be system dependent $PRINTF "test $F_n $TEST... ${YELLOW}value of SO_REUSEADDR not known${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -11206,8 +10919,7 @@ if ! echo "$da" |diff - "${tf}1" >"${tdiff}1"; then echo "$CMD1" cat ${te}1 cat "${tdiff}1" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $rc3 -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" @@ -11218,8 +10930,7 @@ elif [ $rc3 -ne 0 ]; then cat ${te}2 echo "$CMD3" cat ${te}3 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "${tf}3" >"${tdiff}3"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" @@ -11231,13 +10942,11 @@ elif ! echo "$da" |diff - "${tf}3" >"${tdiff}3"; then echo "$CMD3" cat ${te}3 cat "${tdiff}3" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND, SO_REUSEADDR ;; @@ -11252,15 +10961,12 @@ TEST="$NAME: echo via connection to SCTP V4 socket" if ! eval $NUMCOND; then :; elif ! testfeats sctp ip4 >/dev/null || ! runsip4 >/dev/null || ! runssctp4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SCTP4 not available${NORMAL}\n" $N - listCANT="$listCANT $N" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ "$UNAME" = Linux ] && ! grep ^sctp /proc/modules >/dev/null; then # RHEL5 based systems became unusable when an sctp socket was created but # module sctp not loaded $PRINTF "test $F_n $TEST...${YELLOW}load sctp module!${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -11282,18 +10988,15 @@ if [ $? -ne 0 ]; then cat "${te}1" echo "$CMD2" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid1 2>/dev/null wait @@ -11309,12 +11012,10 @@ TEST="$NAME: echo via connection to SCTP V6 socket" if ! eval $NUMCOND; then :; elif ! testfeats sctp ip6 >/dev/null || ! runsip6 >/dev/null || ! runssctp6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SCTP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ "$UNAME" = Linux ] && ! grep ^sctp /proc/modules >/dev/null; then $PRINTF "test $F_n $TEST...${YELLOW}load sctp module!${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -11336,18 +11037,15 @@ if [ $? -ne 0 ]; then cat "${te}1" echo "$CMD2" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null fi # NUMCOND, feats @@ -11380,28 +11078,23 @@ TEST="$NAME: OpenSSL connections survive renogotiation" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! type openssl >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif ! [[ $(echo $OPENSSL_VERSION |awk '{print($2);}') =~ [01].* ]]; then + cant +elif ! re_match "$(echo $OPENSSL_VERSION |awk '{print($2);}')" '[01].*'; then # openssl s_client apparently provides renegotiation only up to version 1.2 $PRINTF "test $F_n $TEST... ${YELLOW}not with OpenSSL $OPENSSL_VERSION${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" -init_openssl_s_client newport tcp4 CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE" #CMD1="openssl s_client -port $PORT -verify 0" # not with openssl 1.1.0g @@ -11419,16 +11112,14 @@ if echo "$da" |diff - ${tf}1 >"$tdiff"; then if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok elif grep -i "Connection refused" "${te}1" >/dev/null; then $PRINTF "$CANT (conn failed)\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else $PRINTF "$FAILED (diff)\n" echo "$CMD0 &" @@ -11437,8 +11128,7 @@ else cat "${te}1" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -11460,21 +11150,17 @@ TEST="$NAME: OpenSSL connections do not block after renogotiation" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! type openssl >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif ! [[ $(echo $OPENSSL_VERSION |awk '{print($2);}') =~ [01].* ]]; then + cant +elif ! re_match "$(echo $OPENSSL_VERSION |awk '{print($2);}')" '[01].*'; then # openssl s_client apparently provides renegotiation only up to version 1.2 $PRINTF "test $F_n $TEST... ${YELLOW}not with OpenSSL $OPENSSL_VERSION${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -11499,16 +11185,14 @@ if echo "$da" |diff - ${tf}1 >"$tdiff"; then if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok elif grep -i "Connection refused" "${te}1" >/dev/null; then $PRINTF "$CANT (conn failed)\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else $PRINTF "$FAILED (diff)\n" echo "$CMD0 &" @@ -11517,8 +11201,7 @@ else cat "${te}1" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -11549,14 +11232,12 @@ $CMD0 </dev/null 1>&0 2>"${te}0" rc0=$? if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -11584,14 +11265,12 @@ $CMD0 </dev/null 1>&0 2>"${te}0" rc0=$? if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -11620,14 +11299,12 @@ $CMD0 </dev/null 1>&0 2>"${te}0" rc0=$? if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -11667,16 +11344,14 @@ if [ $rc1 -ne 0 ]; then echo "$CMD1" cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif grep -q ' W ' "${te}1"; then $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - ${tf}1 >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -11684,12 +11359,10 @@ elif ! echo "$da" |diff - ${tf}1 >"$tdiff"; then cat "${te}0" cat "${te}1" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -11715,14 +11388,12 @@ $CMD0 >/dev/null 2>"${te}0" rc0=$? if [ $rc0 -ne 0 -a -f "$tf" ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -11747,14 +11418,12 @@ $CMD0 >/dev/null 2>"${te}0" rc0=$? if [ $rc0 -ne 0 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -11794,26 +11463,21 @@ if [ $rc1 -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif [ ! -e "$tw" ]; then $PRINTF "$NO_RESULT (no wc -c output)\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant elif [ "$bytes" -eq $(cat "$tw") ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED (incomplete)\n" echo "transferred only $(cat $tw) of $bytes bytes" >&2 @@ -11821,9 +11485,7 @@ else cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -11838,12 +11500,10 @@ TEST="$NAME: OpenSSL server with cipher aNULL " if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -11864,13 +11524,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then #cat "${te}1" #cat "${te}2" #cat "$tdiff" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -11886,10 +11544,10 @@ PROTO=$KEYW proto="$(tolower "$PROTO")" feat="$(tolower "$FEAT")" # test the max-children option on really connection oriented sockets -NAME=${KEYW}MAXCHILDREN +NAME=${KEYW}_L_MAXCHILDREN case "$TESTS" in *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%$feat%*|*%$proto%*|*%socket%*|*%listen%*|*%$NAME%*) -TEST="$NAME: max-children option" +TEST="$NAME: max-children option with $PROTO-LISTEN" # start a listen process with max-children=1; connect with a client, let it # sleep some time before sending data; connect with second client that sends # data immediately. If max-children is working correctly the first data should @@ -11897,12 +11555,10 @@ TEST="$NAME: max-children option" if ! eval $NUMCOND; then :; elif ! testfeats "$FEAT" >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$FEAT not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runs$RUNS >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$(toupper $RUNS) not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else case "X$IPPORT" in "XPORT") @@ -11934,8 +11590,7 @@ relsleep 2 kill $pid1 $pid2 $pid0 2>/dev/null; wait if echo -e "$da 1\n$da 2" |diff - $tf >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -11945,8 +11600,7 @@ else cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -11973,10 +11627,10 @@ RUNS=$(tolower $KEYW) PROTO=$KEYW proto="$(tolower "$PROTO")" # test the max-children option on pseudo connected sockets -NAME=${KEYW}MAXCHILDREN +NAME=${KEYW}_L_MAXCHILDREN case "$TESTS" in *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%$SEL%*|*%socket%*|*%listen%*|*%$NAME%*) -TEST="$NAME: max-children option" +TEST="$NAME: max-children option with $PROTO-LISTEN" # start a listen process with max-children=1; connect with a client, let it # send data and then sleep; connect with second client that wants to send # data immediately, but keep first client active until server terminates. @@ -11985,12 +11639,10 @@ TEST="$NAME: max-children option" if ! eval $NUMCOND; then :; elif ! testfeats "$FEAT" >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$FEAT not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runs$RUNS >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$(toupper $RUNS) not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else case "X$IPPORT" in "XPORT") @@ -12024,8 +11676,7 @@ cpids="$(childpids $pid0)" kill $pid1 $pid2 $pid0 $cpids 2>/dev/null; wait if echo -e "$da 1" |diff - $tf >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -12035,8 +11686,7 @@ else cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -12066,8 +11716,7 @@ TEST="$NAME: test for buffer overflow in readline prompt handling" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats readline pty); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -12085,14 +11734,12 @@ if [ $rc -ne 0 ]; then $PRINTF "${YELLOW}framework failed${NORMAL}\n" elif [ $rc0 -eq 0 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" grep -v ^rc= "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -12122,7 +11769,8 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" RLIMIT_NOFILE="$(ulimit -n)" -if ! [[ "$RLIMIT_NOFILE" =~ ^[0-9][0-9]*$ ]]; then +#if ! [[ "$RLIMIT_NOFILE" =~ ^[0-9][0-9]*$ ]]; then +if ! re_match "$RLIMIT_NOFILE" '^[0-9][0-9]*$'; then $PRINTF "${YELLOW}cannot determine ulimit -n${NORMAL}" else if [ $RLIMIT_NOFILE -gt 1024 ]; then @@ -12154,8 +11802,7 @@ if [ $rc2 -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif [ -f "$tdiff" -a ! -s "$tdiff" ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -12164,8 +11811,7 @@ elif [ -f "$tdiff" -a ! -s "$tdiff" ]; then if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -12174,8 +11820,7 @@ else cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # ulimit -n fi # NUMCOND @@ -12185,7 +11830,9 @@ N=$((N+1)) if false; then # this overflow is not reliably reproducable -# socat up to 2.0.0-b6 did not check the length of the PROXY-CONNECT command line paramters when copying them into the HTTP request buffer. This could lead to a buffer overflow. +# Socat up to 2.0.0-b6 did not check the length of the PROXY-CONNECT command +# line parameters when copying them into the HTTP request buffer. This could +# lead to a buffer overflow. NAME=PROXY_ADDR_OVFL case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%socket%*|*%listen%*|*%$NAME%*) @@ -12215,19 +11862,16 @@ rc1=$? if [ $rc1 -lt 128 ]; then if [ "$EF" ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$UNKNOWN $RED(install ElectricFEnce!)$NORMAL\n" - numCANT=$((num+1)) - listCANT="$listCANT $N" + cant fi else $PRINTF "$FAILED\n" echo "$CMD1" cat "${te}" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -12268,26 +11912,21 @@ if [ -z "$KEEPALIVE" ]; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant elif [ "$KEEPALIVE" = "1" ]; then $PRINTF "$OK\n"; if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED (KEEPALIVE=$KEEPALIVE)\n" echo "$CMD0 &" cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -12307,8 +11946,7 @@ TEST="$NAME: test OPENSSL-CONNECT with bind option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf0="$td/test$N.0.stdout" @@ -12333,8 +11971,7 @@ if [ "$rc1" -ne 0 ]; then echo "$CMD1" cat "$te0" cat "$te1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - $tf1 >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -12342,12 +11979,10 @@ elif ! echo "$da" |diff - $tf1 >"$tdiff"; then cat "${te}0" cat "${te}1" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -12359,14 +11994,13 @@ N=$((N+1)) # had a bug that converted a bit mask of 0 internally to 0xffffffff NAME=TCP4RANGE_0BITS case "$TESTS" in -*%$N%*|*%functions%*|*%fork%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%$NAME%*) +*%$N%*|*%functions%*|*%fork%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%retry%*|*%$NAME%*) TEST="$NAME: correct evaluation of range mask 0" if ! eval $NUMCOND; then :; elif [ -z "$SECONDADDR" ]; then # we need access to a second address $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -12386,24 +12020,20 @@ sleep 1 kill $pid0 2>/dev/null; wait if [ $rc1 != 0 ]; then $PRINTF "${YELLOW}invocation failed${NORMAL}\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! [ -f "$tf" ]; then $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "${YELLOW}diff failed${NORMAL}\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # $SECONDADDR, NUMCOND @@ -12429,8 +12059,7 @@ FEAT=$(echo "$ssldist" |tr a-z A-Z) if ! eval $NUMCOND; then :; elif ! testfeats $FEAT >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$FEAT not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -12469,8 +12098,7 @@ if [ $rc1 != 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif effval="$(grep SOCAT_${SSLDIST}_${MODULE}_${FIELD} "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g")"; [ "$effval" = "$VALUE" ]; then $PRINTF "$OK\n" @@ -12480,8 +12108,7 @@ elif effval="$(grep SOCAT_${SSLDIST}_${MODULE}_${FIELD} "${tf}" |sed -e 's/^[^=] echo "$CMD1" cat "${te}1" fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "expected \"$VALUE\", got \"$effval\"" >&2 @@ -12489,8 +12116,7 @@ else cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND, feats ;; @@ -12552,18 +12178,15 @@ if [ "$ERRNOENT" ]; then echo "$CMD0 &" cat "$te0" cat "$tlog" - let numFAIL=numFAIL+1 - listFAIL="$listFAIL $N" + failed elif [ "$perms" != "600" ]; then $PRINTF "${RED}perms \"$perms\", expected \"600\" ${NORMAL}\n" echo "$CMD0 &" cat "$te0" - let numFAIL=numFAIL+1 - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - let numOK=numOK+1 - listOK="$listOK $N" + ok fi set +xv fi # NUMCOND @@ -12628,18 +12251,15 @@ if [ "$ERRNOENT" ]; then echo "$CMD0 &" cat "$te0" cat "$tlog" - let numFAIL=numFAIL+1 - listFAIL="$listFAIL $N" + failed elif [ "$perms" != "511" ]; then $PRINTF "${RED}perms \"$perms\", expected \"511\" ${NORMAL}\n" echo "$CMD0 &" cat "$te0" - let numFAIL=numFAIL+1 - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - let numOK=numOK+1 - listOK="$listOK $N" + ok fi set +vx fi # NUMCOND @@ -12679,8 +12299,7 @@ TEST="$NAME: $ADDR applies option user" if ! eval $NUMCOND; then :; elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tlog="$td/test$N.log" te0="$td/test$N.0.stderr" @@ -12704,20 +12323,17 @@ if [ "$ERRNOENT" ]; then echo "$CMD0 &" cat "$te0" >&2 cat "$tlog" >&2 - let numFAIL=numFAIL+1 - listFAIL="$listFAIL $N" + failed elif [ "$user" != "$SUBSTUSER" ]; then - $PRINTF "${FAILD}(user \"$user\", expected \"$SUBSTUSER\")\n" + $PRINTF "${FAILED}(user \"$user\", expected \"$SUBSTUSER\")\n" echo "$CMD0 &" cat "$te0" >&2 - let numFAIL=numFAIL+1 - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi set +vx fi # NUMCOND @@ -12777,19 +12393,16 @@ if [ $rc1 != 0 ]; then echo "$CMD0 &" cat "$te0" cat "$tlog" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! [ $crit $tsock ]; then $PRINTF "$OK\n" - let numOK=numOK+1 - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "$te0" cat "$tlog" - let numFAIL=numFAIL+1 - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -12846,19 +12459,16 @@ if [ $rc1 != 0 ]; then echo "$CMD0 &" cat "$te0" cat "$tlog" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! [ $crit $tsock ]; then $PRINTF "$OK\n" - let numOK=numOK+1 - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "$te0" cat "$tlog" - let numFAIL=numFAIL+1 - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -12880,14 +12490,13 @@ case "$TESTS" in TEST="$NAME: SYSTEM address does not shutdown its parents addresses" # start an OpenSSL echo server using SYSTEM:cat # start an OpenSSL client that sends data -# when the client recieves its data and terminates without error the test succeeded +# when the client receives its data and terminates without error the test succeeded # in case of the bug the client issues an error like: # SSL_connect(): error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -12911,8 +12520,7 @@ if [ $rc1 -ne 0 ]; then echo "$CMD1" cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "${tf}1" >"$tdiff" 2>&1; then $PRINTF "$FAILED\n" echo "diff:" @@ -12921,12 +12529,10 @@ elif ! echo "$da" |diff - "${tf}1" >"$tdiff" 2>&1; then echo "$CMD1" cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -12958,19 +12564,16 @@ if [ ! -f "$t0rc" ]; then echo "no return code of CMD0 stored" >&2 echo "$CMD0 &" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo 1 |diff - "$t0rc" >"$tdiff"; then $PRINTF "$FAILED\n" echo "CMD0 exited with $(cat $t0rc), expected 1" echo "$CMD0 &" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -12998,12 +12601,10 @@ TEST="$NAME: test OpenSSL method $method" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! socat -hhh |grep -q "^[[:space:]]*openssl-method[[:space:]]"; then $PRINTF "test $F_n $TEST... ${YELLOW}Option openssl-method not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -13016,8 +12617,7 @@ CMD1="$SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,opensslmethod=$method,veri printf "test $F_n $TEST... " $N if [ "$method" = DTLS1 -a "$(echo -e "$OPENSSL_VERSION\n1.0.2" |sort |tail -n 1)" = "$OPENSSL_VERSION_GOOD" ]; then $PRINTF "${YELLOW}might hang, skipping${NORMAL}\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else $CMD0 >/dev/null 2>"${te}0" & pid0=$! @@ -13030,13 +12630,11 @@ fi echo "$da" |diff - "${tf}1" >"$tdiff" 2>/dev/null if [ $w0 -eq 0 ] && [ -f "${tf}1" ] && ! [ -s "$tdiff" ]; then $PRINTF "${YELLOW}WARN${NORMAL} (obsolete method succeeds)\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$OK (obsolete method fails)\n" cat "$tdiff" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi if [ "$VERBOSE" ]; then echo " $CMD0" @@ -13066,19 +12664,18 @@ TEST="$NAME: test OpenSSL method $method" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! socat -hhh |grep -q "^[[:space:]]*openssl-method[[:space:]]"; then $PRINTF "test $F_n $TEST... ${YELLOW}Option openssl-method not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" -if [[ "$method" =~ DTLS* ]]; then +#if [[ "$method" =~ DTLS* ]]; then +if re_match "$method" '^DTLS.*'; then newport udp4 else newport tcp4 @@ -13088,12 +12685,12 @@ CMD1="$SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,openssl-method=$method,ver printf "test $F_n $TEST... " $N if [ "$method" = DTLS1 -a "$(echo -e "$OPENSSL_VERSION\n1.0.2" |sort |tail -n 1)" = "$OPENSSL_VERSION_GOOD" ]; then $PRINTF "${YELLOW}might hang, skipping${NORMAL}\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else $CMD0 >/dev/null 2>"${te}0" & pid0=$! -if [[ "$method" =~ DTLS* ]]; then +#if [[ "$method" =~ DTLS* ]]; then +if re_match "$method" '^DTLS.*'; then waitudp4port $PORT 1 else waittcp4port $PORT 1 @@ -13103,8 +12700,7 @@ rc1=$? kill $pid0 2>/dev/null; wait if echo "$da" |diff - "${tf}1" >"$tdiff"; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok if [ "$VERBOSE" ]; then echo " $CMD0" echo " echo \"$da\" |$CMD1" @@ -13116,8 +12712,7 @@ else echo "$CMD1" cat "${te}1" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed #esac fi fi # !DTLS1 hang @@ -13139,17 +12734,14 @@ TEST="$NAME: security of OpenSSL server with openssl-min-proto-version" if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions openssl-min-proto-version); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! [ "$OPENSSL_LATEST_PROTO_VERSION" -a "$OPENSSL_BEFORELAST_PROTO_VERSION" -a \ "$OPENSSL_LATEST_PROTO_VERSION" != "$OPENSSL_BEFORELAST_PROTO_VERSION" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}cannot determine two available SSL/TLS versions${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv newport tcp4 @@ -13177,15 +12769,13 @@ $CMD >/dev/null 2>"${te}" rc=$? if [ $rc -eq 1 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD" cat "${te}" echo "command did not terminate with error!" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -13214,12 +12804,10 @@ if [ $rc0 -eq 0 ]; then $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -13248,12 +12836,10 @@ if [ $rc0 -eq 0 ]; then $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -13275,8 +12861,7 @@ TEST="$NAME: test the so-reuseaddr option" if ! eval $NUMCOND; then :; elif ! feat=$(testoptions so-reuseaddr); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport tcp4; tp="$PORT" tf="$td/test$N.stdout" @@ -13304,8 +12889,7 @@ if ! echo "$da" |diff - "$tf"; then $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n" echo "$CMD0 &" echo "$CMD1" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $rc3 -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" @@ -13313,8 +12897,7 @@ elif [ $rc3 -ne 0 ]; then echo "$CMD2 &" echo "$CMD3" cat "${te}2" "${te}3" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "${tf}3"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" @@ -13322,13 +12905,11 @@ elif ! echo "$da" |diff - "${tf}3"; then echo "$CMD2 &" echo "$CMD3" echo "$da" |diff - "${tf}3" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND, SO_REUSEADDR ;; @@ -13349,8 +12930,7 @@ TEST="$NAME: test the so-reuseport option" if ! eval $NUMCOND; then :; elif ! feat=$(testoptions so-reuseport); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport tcp4; tp="$PORT" tf="$td/test$N.stdout" @@ -13381,8 +12961,7 @@ if ! echo "$da2" |diff - "${tf}2"; then cat "${te}1" echo "$CMD2" cat "${te}2" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $rc3 -ne 0 ]; then $PRINTF "$FAILED:\n" echo "$CMD0 &" @@ -13393,8 +12972,7 @@ elif [ $rc3 -ne 0 ]; then cat "${te}2" echo "$CMD3" cat "${te}3" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da2" |diff - "${tf}2"; then $PRINTF "$FAILED:\n" echo "$CMD0 &" @@ -13406,8 +12984,7 @@ elif ! echo "$da2" |diff - "${tf}2"; then echo "$CMD3" cat "${te}3" echo "$da2" |diff - "${tf}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da3" |diff - "${tf}3"; then $PRINTF "$FAILED:\n" echo "$CMD0 &" @@ -13419,13 +12996,11 @@ elif ! echo "$da3" |diff - "${tf}3"; then echo "$CMD3" cat "${te}3" echo "$da3" |diff - "${tf}3" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND, SO_REUSEPORT ;; @@ -13451,15 +13026,13 @@ eval "$CMD0" >"${tf}0" 2>"${te}0" rc1=$? if echo "$da" |diff - "${tf}0" >"$tdiff"; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -13479,12 +13052,10 @@ TEST="$NAME: test OpenSSL ECDHE" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! openssl ciphers |grep -q '\<ECDHE\>'; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl: cipher ECDHE not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -13511,12 +13082,10 @@ if [ $rc1 -ne 0 ]; then echo "client and stderr:" >&2 echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif echo "$da" |diff - "${tf}1" >"$tdiff"; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "server and stderr:" >&2 @@ -13525,8 +13094,7 @@ else echo "client and stderr:" >&2 echo "$CMD0 &" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -13544,7 +13112,18 @@ TEST="$NAME: is option ipv6-join-group used" # Terminate immediately, do not transfer data. # If socat exits with 0 the test succeeds. # Up to 1.7.3.1 it failed with "1 option(s) could not be used" -if ! eval $NUMCOND; then :; else +if ! eval $NUMCOND; then :; +elif ! cond=$(checkconds \ + "" \ + "" \ + "" \ + "IP6 UDP GOPEN" \ + "UDP6-RECV GOPEN" \ + "ipv6-join-group" \ + "udp6" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant +else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -13556,14 +13135,12 @@ $CMD0 >/dev/null 2>"${te}0" rc0=$? if [ $rc0 -eq 0 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -13577,7 +13154,7 @@ NAME=DIAG_FDIN case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%exec%*|*%$NAME%*) TEST="$NAME: test use of fdin=3" -# Use FD 3 explicitely with fdin and test if Socat passes data to executed +# Use FD 3 explicitly with fdin and test if Socat passes data to executed # program if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" @@ -13592,19 +13169,16 @@ if [ $rc0 -ne 0 ]; then $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif echo "$da" |diff - ${tf}0 >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -13624,13 +13198,11 @@ $CMD0 >/dev/null 2>"${te}0" rc0=$? if [ "$rc0" = "1" ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi ;; # NUMCOND esac @@ -13661,16 +13233,14 @@ $CMD1 2>"${te}1" rc0=$? if [ $rc0 -eq 0 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -13697,14 +13267,12 @@ printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"${te}0" if ! grep -q "ai_socktype not supported" ${te}0; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -13735,16 +13303,14 @@ rc1=$? kill $pid0 2>/dev/null; wait if [ $(grep "socket 2 (fd .*) is at EOF" ${te}0 |wc -l) -eq 1 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -13780,19 +13346,16 @@ if [ $rc0 -eq 0 ]; then $PRINTF "$FAILED (rc=$rc0)\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif [ $rc0 -eq 1 ]; then if grep -q "buffer size option (-b) to big" "${te}0"; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED (rc=$rc0)\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi fi # NUMCOND @@ -13819,14 +13382,12 @@ if grep -q -i -e "syntax error" -e "unexpected end" "${te}0"; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0" >&2; fi if [ "$debug" ]; then cat ${te} >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -13848,8 +13409,7 @@ TEST="$NAME: Service name resolution works with SCTP" if ! eval $NUMCOND; then :; elif ! runssctp4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SCTP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -13859,18 +13419,15 @@ printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"${te}0" if [ $? -eq 0 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok elif grep -q "Connection refused" ${te}0; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -13888,8 +13445,7 @@ TEST="$NAME: echo via file with o-direct" if ! eval $NUMCOND; then :; elif ! testoptions o-direct >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}o-direct not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.file" to="$td/test$N.stdout" @@ -13907,29 +13463,26 @@ if [ $rc -ne 0 ] && grep -q "Invalid argument" "$te" && [ $UNAME = Linux ]; then $PRINTF "${FAILED}\n" echo "$CMD" >&2 cat "$te" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" ;; - *) $PRINTF "${YELLOW}inable file system${NORMAL}\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" ;; + failed ;; + *) $PRINTF "${YELLOW}unsupported file system${NORMAL}\n" + if [ "$VERBOSE" ]; then echo "$CMD"; fi + if [ "$DEBUG" ]; then cat "${te}" >&2; fi + cant ;; esac elif [ $rc -ne 0 ]; then $PRINTF "${FAILED}:\n" echo "$CMD" >&2 cat "$te" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$to" >$tdiff; then $PRINTF "${FAILED}\n" echo "$CMD" >&2 cat "$te" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # command ok fi ;; # NUMCOND, feats esac @@ -13963,8 +13516,7 @@ rc1=$? kill $pid0 2>/dev/null; wait if test -S $uns && ! test -S $unc; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -13972,8 +13524,7 @@ else ls -ld $uns $unc cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -14007,8 +13558,7 @@ rc1=$? kill $pid0 2>/dev/null; wait if test -S $uns && ! test -S $unc; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -14016,8 +13566,7 @@ else ls -ld $uns $unc cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -14035,20 +13584,19 @@ TEST="$NAME: OpenSSL DTLS client" if ! eval $NUMCOND; then :; elif ! a=$(testfeats ip4 udp openssl); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs openssl-dtls-client); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! type openssl >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not found${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant +elif init_openssl_s_server; re_match "$method" '^DTLS.*' && [ -z "$OPENSSL_S_SERVER_DTLS" ]; then + $PRINTF "test $F_n $TEST... ${YELLOW}DTLS not available in s_server${NORMAL}\n" $N + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -14073,13 +13621,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD" cat "$te" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "$te"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -14095,25 +13641,23 @@ TEST="$NAME: OpenSSL DTLS server" if ! eval $NUMCOND; then :; elif ! a=$(testfeats ip4 udp openssl) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs openssl-dtls-server); then $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! type openssl >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not found${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-ce] ]]; then + cant +elif init_openssl_s_client; re_match "$method" '^DTLS.*' && [ -z "$OPENSSL_S_CLIENT_DTLS" ]; then + $PRINTF "test $F_n $TEST... ${YELLOW}DTLS not available in s_client${NORMAL}\n" $N + cant +elif re_match "$(openssl version |awk '{print($2);}')" '^0\.9\.8[a-ce]'; then # also on NetBSD-4 with openssl-0.9.8e $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -14133,8 +13677,7 @@ rc=$? kill $pid1 2>/dev/null; wait if echo "$da" |diff - $tf >"$tdiff"; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD1 &" @@ -14142,8 +13685,7 @@ else echo "$CMD" cat "$te" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -14158,12 +13700,10 @@ TEST="$NAME: OpenSSL server authentication with SubjectAltName (hostname)" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestaltcert testalt tf="$td/test$N.stdout" @@ -14185,13 +13725,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD1" >&2 cat "${te}1" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -14206,12 +13744,10 @@ TEST="$NAME: OpenSSL server authentication with SubjectAltName (IPv4 address)" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 openssl >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestaltcert testalt tf="$td/test$N.stdout" @@ -14233,13 +13769,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD1" >&2 cat "${te}1" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -14254,12 +13788,10 @@ TEST="$NAME: OpenSSL server authentication with SubjectAltName (IPv6 address)" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip6 openssl >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestaltcert testalt tf="$td/test$N.stdout" @@ -14281,13 +13813,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD1" >&2 cat "${te}1" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -14307,8 +13837,7 @@ TEST="$NAME: raw dump of transferred data" if ! eval $NUMCOND; then :; elif [ $($SOCAT -h |grep -e ' -[rR] ' |wc -l) -lt 2 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}Options -r, -R not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -14338,12 +13867,10 @@ if ! echo "$da1" |diff - $tr1 >$tdiff1 || ! echo "$da2" |diff - $tr2 >$tdiff2; t cat $tdiff1 >&2 echo "Right-to-left:" >&2 cat $tdiff2 >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -14363,16 +13890,13 @@ SNISERVER=badssl.com if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions openssl-snihost); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ -z "$INTERNET" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -14384,14 +13908,12 @@ $CMD0 >/dev/null 2>"${te}0" rc0=$? if [ $rc0 -eq 0 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" >&2 cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -14412,16 +13934,13 @@ SNISERVER=badssl.com if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions openssl-no-sni); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ -z "$INTERNET" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -14433,14 +13952,12 @@ $CMD0 >/dev/null 2>"${te}0" rc0=$? if [ $rc0 -ne 0 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" >&2 cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -14456,12 +13973,10 @@ TEST="$NAME: test the accept-timeout option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs tcp); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions accept-timeout); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else # Just start a process with accept-timeout 1s and check if it still runs 2s later # but before this, we test if the process waits at all @@ -14481,8 +13996,7 @@ if ! kill $pid1 2>"$tk1"; then echo $CMD1 >&2 cat "$te1" >&2 cat "$tk1" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else # Second, set accept-timeout and see if socat exits before kill CMD2="$TRACE $SOCAT $opts TCP-LISTEN:$PORT,reuseaddr,accept-timeout=$(reltime 1) PIPE" @@ -14494,12 +14008,10 @@ if kill $pid2 2>"$tk2"; then echo "$CMD2" >&2 cat "$te2" >&2 cat "$tk2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi wait @@ -14519,8 +14031,7 @@ TEST="$NAME: test UDP-DATAGRAM ignoring peerport" if ! eval $NUMCOND; then : elif [ $(echo $E "$SOCAT_VERSION\n1.7.3.4" |sort -n |tail -n 1) = 1.7.3.4 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}Only with Socat 1.7.4.0 or higher${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -14541,8 +14052,7 @@ sleep 0.1 kill $pid0 2>/dev/null; wait if [ -f ${tf}0 ] && echo "$da" |diff - ${tf}0 >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" >&2 @@ -14550,8 +14060,7 @@ else echo "$CMD1" >&2 cat "${te}1" >&2 cat "${tdiff}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -14567,16 +14076,13 @@ TEST="$NAME: proxy-authorization-file option" if ! eval $NUMCOND; then :; elif ! testfeats proxy >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testoptions proxy-authorization-file >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option proxy-authorization-file not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ta="$td/test$N.auth" tf="$td/test$N.stdout" @@ -14602,8 +14108,7 @@ if [ $rc1 -ne 0 ]; then echo "$CMD1" >&2 cat "${te}1" >&2 cat "${tf}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! grep -q '^Proxy-authorization: Basic dXNlcjpzM2NyM3QK$' ${tf}0; then $PRINTF "$FAILED:\n" echo "$CMD0 &" >&2 @@ -14612,13 +14117,11 @@ elif ! grep -q '^Proxy-authorization: Basic dXNlcjpzM2NyM3QK$' ${tf}0; then cat "${te}1" >&2 cat "${tf}0" >&2 echo "Authorization string not in client request" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -14637,8 +14140,7 @@ TEST="$NAME: test communication via VSOCK loopback socket" if ! eval $NUMCOND; then :; elif ! fea=$(testfeats VSOCK); then $PRINTF "test $F_n $TEST... ${YELLOW}$fea not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -14656,36 +14158,30 @@ rc1=$? kill $pid0 2>/dev/null; wait if [ $rc1 -ne 0 ] && [ "$UNAME" != Linux ]; then $PRINTF "${YELLOW}works only on Linux?${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif [ $rc1 -ne 0 ] && [ "$UNAME" = Linux ] && ! [[ $UNAME_R =~ ^[6-9]\.* ]] && ! [[ $UNAME_R =~ ^5\.[6-]\.* ]] && ! [[ $UNAME_R =~ ^5\.[1-9][0-9].* ]]; then + cant +elif [ $rc1 -ne 0 ] && [ "$UNAME" = Linux ] && ! re_match "$UNAME_R" '^[6-9]\..*' && ! re_match "$UNAME_R" '^5\.[6-]\..*' && ! re_match "$UNAME_R" '^5\.[1-9][0-9].*'; then $PRINTF "${YELLOW}works only on Linux from 5.6${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif grep -q "No such device" "${te}1"; then $PRINTF "${YELLOW}Loopback does not work${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $rc1 -ne 0 ]; then $PRINTF "$FAILED\n" echo "$CMD0 &" >&2 cat "${te}0" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif echo "$da" |diff - ${tf}1 >${tdiff}$N; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" >&2 cat "${te}0" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -14707,16 +14203,13 @@ TEST="$NAME: OpenSSL stream from client to server" if ! eval $NUMCOND; then :; elif ! a=$(testfeats ip4 tcp openssl); then $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs openssl-listen openssl-connect); then $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv ti="$td/test$N.datain" @@ -14742,12 +14235,10 @@ if [ $rc1 -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif diff $ti $to >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" >&2 @@ -14757,8 +14248,7 @@ else echo "diff:" >&2 head -n 2 $tdiff >&2 echo ... >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -14779,16 +14269,13 @@ TEST="$NAME: OpenSSL stream from server to client" if ! eval $NUMCOND; then :; elif ! a=$(testfeats ip4 tcp openssl); then $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs openssl-listen openssl-connect); then $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv ti="$td/test$N.datain" @@ -14814,12 +14301,10 @@ if [ $rc1 -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif diff $ti $to >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" >&2 @@ -14829,8 +14314,7 @@ else echo "diff:" >&2 head -n 2 $tdiff >&2 echo ... >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -14850,21 +14334,17 @@ TEST="$NAME: OpenSSL DTLS transfer from client to server" if ! eval $NUMCOND; then :; elif ! a=$(testfeats ip4 udp openssl); then $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs openssl-dtls-listen openssl-dtls-connect); then $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-ce] ]]; then + cant +elif re_match "$(openssl version |awk '{print($2);}')" '^0.9.8[a-ce]'; then # also on NetBSD-4 with openssl-0.9.8e $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv ti="$td/test$N.datain" @@ -14890,12 +14370,10 @@ if [ $rc1 -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif diff $ti $to >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" >&2 @@ -14905,8 +14383,7 @@ else echo "diff:" >&2 head -n 2 $tdiff >&2 echo ... >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -14926,21 +14403,17 @@ TEST="$NAME: OpenSSL DTLS transfer from server to client" if ! eval $NUMCOND; then :; elif ! a=$(testfeats ip4 udp openssl); then $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs openssl-dtls-listen openssl-dtls-connect); then $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-ce] ]]; then + cant +elif re_match "$(openssl version |awk '{print($2);}')" '^0.9.8[a-ce]'; then # also on NetBSD-4 with openssl-0.9.8e $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv ti="$td/test$N.datain" @@ -14966,12 +14439,10 @@ if [ $rc1 -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif diff $ti $to >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" >&2 @@ -14981,8 +14452,7 @@ else echo "diff:" >&2 head -n 2 $tdiff >&2 echo ... >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15001,16 +14471,13 @@ TEST="$NAME: test diverse of socket,openssl params" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! type openssl >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -15031,19 +14498,17 @@ sleep 0.5 kill $pid0 2>/dev/null; wait if [ $rc1 -ne 0 ]; then $PRINTF "$CANT\n" - numCANT=$((numCANT+1)) + cant elif [ ! -e $trc0 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" >&2 cat "${te}0" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15062,12 +14527,13 @@ TEST="$NAME: Test if OpenSSL server may be crashed by client cert with IPv6 addr if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant +elif ! runsip6 >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}Cannot generate cert with IPv6 address${NORMAL}\n" $N + cant else gentestcert testsrv gentestaltcert testalt @@ -15087,16 +14553,14 @@ rc1=$? kill $pid0 2>/dev/null; wait if [ $rc1 -eq 0 ] && echo "$da" |diff - "${tf}0" >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" >&2 cat "${te}0" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15127,14 +14591,12 @@ if [ $rc -ne 0 ]; then if [ "$VERBOSE" ]; then echo "$CMD &" >&2 fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD &" >&2 cat "${te}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15153,8 +14615,7 @@ TEST="$NAME: Is the fs related user option on ABSTRACT socket applied to FD" if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -15170,14 +14631,12 @@ if [ $rc -eq 0 ]; then if [ "$VERBOSE" ]; then echo "$CMD" >&2 fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD" >&2 cat "${te}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15207,26 +14666,22 @@ if [ ! -f "$ts" ]; then echo "$CMD" >&2 cat "${te}" >&2 fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ ! -s "$ts" ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD" >&2 fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD &" >&2 cat "${te}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) # Socats access to different types of file system entries using various kinds @@ -15294,8 +14749,7 @@ if [ $rc1 != 1 ]; then fi echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif nerr=$(grep ' E ' "${te}1" |wc -l); test "$nerr" -ne 1; then $PRINTF "$FAILED ($nerr error message(s) instead of 1)\n" if [ "$pid0" ]; then @@ -15304,16 +14758,14 @@ elif nerr=$(grep ' E ' "${te}1" |wc -l); test "$nerr" -ne 1; then fi echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then if [ "$pid0" ]; then echo "$CMD0 &" >&2; fi echo "$CMD1" >&2 fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi set +vx fi # NUMCOND @@ -15364,7 +14816,7 @@ orphaned gopen # Up to 1.7.4.3 this terminated immediately on connection refused NAME=TCP_TIMEOUT_RETRY case "$TESTS" in -*%$N%*|*%functions%*|*%bugs%*|*%tcp%*|*%socket%*|*%listen%*|*%$NAME%*) +*%$N%*|*%functions%*|*%bugs%*|*%tcp%*|*%socket%*|*%listen%*|*%retry%*|*%$NAME%*) TEST="$NAME: TCP with options connect-timeout and retry" # In background run a delayed echo server # In foreground start TCP with connect-timeout and retry. On first attempt the @@ -15389,24 +14841,21 @@ if [ $rc1 -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif echo "$da" |diff - "${tf}1" >$tdiff; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &" >&2 echo "$CMD1" >&2 fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" >&2 cat "${te}0" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15436,19 +14885,16 @@ if [ $rc0 -eq 0 ]; then if [ "$VERBOSE" ]; then echo "$CMD0" >&2 fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" >&2 cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) # Up to 1.7.4.3 there was a bug with the lowport option: @@ -15477,29 +14923,26 @@ rc1=$? LOWPORT=$(grep '[DE] bind(.*:' $te |sed 's/.*:\([0-9][0-9]*\)[}]*,.*/\1/' |head -n 1) #echo "LOWPORT=\"$LOWPORT\"" >&2 #type socat >&2 -if [[ $LOWPORT =~ [0-9][0-9]* ]] && [ "$LOWPORT" -ge 640 -a "$LOWPORT" -le 1023 ]; then +#if [[ $LOWPORT =~ [0-9][0-9]* ]] && [ "$LOWPORT" -ge 640 -a "$LOWPORT" -le 1023 ]; then +if re_match "$LOWPORT" '^[0-9][0-9]*' ]] && [ "$LOWPORT" -ge 640 -a "$LOWPORT" -le 1023 ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok elif $SOCAT -V |grep -q "undef WITH_SYCLS"; then $PRINTF "$CANT (no SYCLS)\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else $PRINTF "$FAILED\n" echo "$CMD" cat "${te}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) # Test if trailing garbage in integer type options gives error @@ -15519,14 +14962,12 @@ printf "test $F_n $TEST... " $N $CMD0 </dev/null >/dev/null 2>"${te}0" if grep -q "missing numerical value" "${te}0"; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15552,14 +14993,12 @@ if grep -q "trailing garbage" "${te}0"; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0" >&2; fi if [ "$debug" ]; then cat ${te} >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15589,16 +15028,14 @@ if [ "$target" = "$tf" ]; then echo "ln -s \"$tf\" \"$tl\"" echo "$FILAN -f "$tl" 2>$te |tail -n 1 |sed 's/.*LINKTARGET=\([^ ]*\)/\1/'" fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "touch \"$tf\"" >&2 echo "ln -s \"$tf\" \"$tl\"" >&2 echo "$FILAN -f "$tl" 2>$te |tail -n 1 |sed 's/.*LINKTARGET=\([^ ]*\)/\1/'" >&2 cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi kill $spid 2>/dev/null wait @@ -15652,8 +15089,7 @@ for addr in exec system; do cat "${te}0" echo "{ echo -n \"${da:0:20}\"; relsleep 1; echo \"${da:20}\"; } |$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "${tf}1" >"$tdiff"; then $PRINTF "$FAILED (diff)\n" echo "$CMD0 &" >&2 @@ -15662,16 +15098,14 @@ for addr in exec system; do cat "${te}1" >&2 echo "diff:" >&2 cat $tdiff >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &" >&2 echo "{ echo -n \"${da:0:20}\"; relsleep 1; echo \"${da:20}\"; } |$CMD1" >&2 fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi MICROS=$SAVEMICS fi # NUMCOND @@ -15692,12 +15126,10 @@ TEST="$NAME: Dalan syntax error does not raise SIGSEGV" if ! eval $NUMCOND; then : elif ! a=$(testfeats GOPEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs - GOPEN SOCKET-LISTEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -15711,21 +15143,18 @@ if [ $rc1 -eq 1 ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD"; fi if [ "$DEBUG" ]; then cat "${te}" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok elif [ $rc1 -eq 139 ]; then $PRINTF "$FAILED\n" echo "$CMD" cat "${te}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else - # soemthing unexpected happened + # Something unexpected happened $PRINTF "$CANT\n" echo "$CMD" cat "${te}" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant fi fi # NUMCOND ;; @@ -15745,27 +15174,23 @@ TEST="$NAME: filan -s displays TCP etc" if ! eval $NUMCOND; then : elif ! a=$(testfeats STDIO IP4 TCP LISTEN EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs STDIO TCP4 TCP4-LISTEN EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions so-reuseaddr nofork ) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" -CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,reuseaddr EXEC:'$FILAN -s',nofork" -CMD1="$TRACE $SOCAT $opts -t $T4 - TCP4:localhost:$PORT" +CMD0="$TRACE $SOCAT $opts -t $T4 TCP4-LISTEN:$PORT,reuseaddr EXEC:'$FILAN -s',nofork" +CMD1="$TRACE $SOCAT $opts -t $T8 - TCP4:localhost:$PORT" printf "test $F_n $TEST... " $N eval "$CMD0" >/dev/null 2>"${te}0" & pid0=$! @@ -15780,8 +15205,7 @@ if [ $rc1 -eq 0 -a "$result" = tcp ]; then if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" if [ $rc1 -ne 0 ]; then @@ -15793,13 +15217,11 @@ else cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) @@ -15818,20 +15240,16 @@ TEST="$NAME: Restoring of terminal settings" if ! eval $NUMCOND; then : elif ! $(type stty >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}stty not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testfeats STDIO SYSTEM PTY GOPEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs - STDIO SYSTEM GOPEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions cfmakeraw pty setsid ctty stderr) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else te="$td/test$N.stderr" tx0="$td/test$N.stty0" @@ -15846,21 +15264,18 @@ if diff $tx0 $tx1 >$tdiff 2>&1; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD &"; fi if [ "$DEBUG" ]; then cat "${te}" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD" cat "${te}" >&2 cat "${te}.outer" >&2 cat $tdiff >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) @@ -15875,12 +15290,10 @@ TEST="$NAME: Socat does not leak FDs to EXEC'd program" if ! eval $NUMCOND; then :; elif ! a=$(testaddrs STDIO EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions stderr) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -15894,20 +15307,17 @@ if [ "$(cat "${tf}" |grep -v ' door ' |wc -l)" -eq 3 ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD"; fi if [ "$DEBUG" ]; then cat "${te}" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD" >&2 cat "${te}" >&2 cat "${tf}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) # Test if Socat makes the sniffing file descriptos (-r, -R) CLOEXEC to not leak @@ -15922,12 +15332,10 @@ TEST="$NAME: Socat does not leak sniffing FDs" if ! eval $NUMCOND; then :; elif ! a=$(testaddrs STDIO EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions stderr) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -15941,20 +15349,17 @@ if [ "$(cat "${tf}" |grep -v ' door ' |wc -l)" -eq 3 ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD"; fi if [ "$DEBUG" ]; then cat "${te}" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD" >&2 cat "${te}" >&2 cat "${tf}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) @@ -15975,20 +15380,16 @@ TEST="$NAME: ${KEYW}-RECVFROM with fork option" if ! eval $NUMCOND; then :; elif ! F=$(testfeats $FEAT STDIO SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs - STDIO SYSTEM $PROTO-RECVFROM $PROTO-SENDTO); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions fork ) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runs$RUNS >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$(toupper $RUNS) not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else case "X$IPPORT" in "XPORT") @@ -16028,8 +15429,7 @@ if $ECHO "$da 2\n$da 1" |diff -u - $tf >$tdiff; then if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -16040,9 +15440,7 @@ else cat "${te}2" >&2 echo "diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -16065,16 +15463,13 @@ TEST="$NAME: Option -S can turn off logging of SIGTERM" if ! eval $NUMCOND; then :; elif ! $SOCAT -h | grep -e " -S\>" >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option -S not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -16091,16 +15486,13 @@ if ! grep "exiting on signal" ${te}0 >/dev/null; then if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$DEBUG" ]; then echo "kill -TERM <pid>" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "${te}0" >&2 echo "kill -TERM <pid>" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -16118,16 +15510,13 @@ TEST="$NAME: Option -S can turn on logging of signal 31" if ! eval $NUMCOND; then :; elif ! $SOCAT -h | grep -e " -S\>" >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option -S not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -16144,16 +15533,13 @@ if grep "exiting on signal" ${te}0 >/dev/null; then if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$DEBUG" ]; then echo "kill -31 <pid>" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "${te}0" >&2 echo "kill -31 <pid>" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -16169,24 +15555,19 @@ TEST="$NAME: PROXY-CONNECT with option http-version" if ! eval $NUMCOND; then :; elif ! $(type proxyecho.sh >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}proxyecho.sh not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats IP4 TCP LISTEN EXEC STDIO PROXY); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs TCP4-LISTEN EXEC STDIO PROXY-CONNECT); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions so-reuseaddr crlf pf proxyport http-version) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ts="$td/test$N.sh" tf="$td/test$N.stdout" @@ -16208,22 +15589,19 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" >&2 echo "diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$debug" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$debug" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait fi ;; # NUMCOND, feats esac -PORT=$((PORT+1)) N=$((N+1)) @@ -16235,23 +15613,20 @@ TEST="$NAME: test the so-rcvtimeo option with DTLS" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO OPENSSL); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO DTLS); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions verify so-rcvtimeo) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else # We need a hanging connection attempt, guess an address for this -HANGIP=0.0.0.1 +#HANGIP=0.0.0.1 # some OSes refuse to end to this address +HANGIP=8.8.8.9 # 2025 this hangs... te1="$td/test$N.stderr1" tk1="$td/test$N.kill1" te2="$td/test$N.stderr2" @@ -16266,8 +15641,7 @@ if ! kill -0 $pid1 2>"$tk1"; then $PRINTF "${YELLOW}does not hang${NORMAL}\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant wait else # DTLS restarts read() a few times @@ -16277,21 +15651,23 @@ CMD2="$TRACE $SOCAT $opts - DTLS:$HANGIP:1,verify=0,so-rcvtimeo=$(reltime 1)" $CMD2 >"$te1" 2>$te2 </dev/null & pid2=$! relsleep 8 # in OpenSSL 1.1.1f DTLS takes two timeouts -if kill $pid2 2>"$tk2"; then - $PRINTF "$FAILED\n" +sleep 0.02 # in OpenSSL 3.0.13 SSL_CTX_clear_mode() needs e.g. 0.02s +kill $pid2 2>"$tk2" +prc2=$? +wait +if [ $prc2 -eq 0 ]; then + $PRINTF "$FAILED (not timeout)\n" echo "$CMD2" >&2 cat "$te2" >&2 cat "$tk2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed while kill $pid2 2>/dev/null; do :; done wait else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD2 &"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi wait @@ -16313,20 +15689,16 @@ TEST="$NAME: sniff file names with variables" if ! eval $NUMCOND; then :; elif ! A=$(testfeats IP4 TCP LISTEN PIPE STDIO); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs - TCP4 TCP4-LISTEN PIPE STDIO); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions so-reuseaddr fork) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -16353,9 +15725,7 @@ if [ $rc1a != 0 -o $rc1b != 0 ]; then cat "${te}1a" >&2 echo "$CMD1" cat "${te}1b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif test $(ls -l $td/test$N.*.log |wc -l) -eq 4 && test $(ls $td/test$N.*.log |head -n 1 |wc -c) -ge 56; then # Are the names correct? @@ -16368,8 +15738,7 @@ elif test $(ls -l $td/test$N.*.log |wc -l) -eq 4 && if [ "$DEBUG" ]; then cat "${te}1a" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok elif test -f $td/test$N.\$PROGNAME-\$TIMESTAMP.\$MICROS-\$SERVER0_PEERADDR-\$\$.in.log; then $PRINTF "$FAILED (vars not resolved)\n" echo "$CMD0 &" @@ -16378,9 +15747,7 @@ elif test -f $td/test$N.\$PROGNAME-\$TIMESTAMP.\$MICROS-\$SERVER0_PEERADDR-\$\$. cat "${te}1a" >&2 echo "$CMD1" cat "${te}1b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$FAILED (unknown)\n" echo "$CMD0 &" @@ -16389,9 +15756,7 @@ else cat "${te}1a" >&2 echo "$CMD1" cat "${te}1b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -16409,20 +15774,16 @@ TEST="$NAME: Socat option --statistics" if ! eval $NUMCOND; then :; elif ! $(type >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}tee not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats STATS STDIO SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions pty cfmakeraw) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -16437,21 +15798,17 @@ if [ $rc0 -ne 0 ]; then $PRINTF "$CANT\n" if [ "$VERBOSE" ]; then echo "$CMD0"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(grep STATISTICS "${te}0" |wc -l) -eq 2 ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -16468,53 +15825,53 @@ TEST="$NAME: statistics on SIGUSR1" if ! eval $NUMCOND; then :; elif ! $(type tee >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}tee not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! $(type pkill >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}pkill not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats STATS STDIO SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions pty cfmakeraw) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts STDIO SYSTEM:'tee /dev/stdout 2>/dev/null',pty,cfmakeraw" -#set -vx -printf "test $F_n $TEST... " $N -{ echo "$da"; relsleep 10; } |eval "$CMD0" >"${tf}0" 2>"${te}0" & -pid0=$! -relsleep 2 TTY=$(tty |sed 's|/dev/||') -pkill -USR1 -t $TTY socat || { echo "pkill -t $TTY -USR1 socat"; } +CMD1="pkill -USR1 -t $TTY socat" +printf "test $F_n $TEST... " $N +# On Fedora-41 pkill can be slow (eg.20ms) +{ echo "$da"; relsleep 20; } |eval "$CMD0" >"${tf}0" 2>"${te}0" & +pid0=$! +#date +'%Y-%m-%dT%H:%M:%S.%N' >>"${te}1" relsleep 2 -pkill -t $TTY socat +#date +'%Y-%m-%dT%H:%M:%S.%N' >>"${te}1" +$CMD1 2>"${te}1" +relsleep 2 +#date +'%Y-%m-%dT%H:%M:%S.%N' >>"${te}1" wait +pkill -t $TTY socat >>"${te}1" if [ "$(grep STATISTICS "${te}0" |wc -l)" -eq 2 ]; then $PRINTF "$OK\n" - if [ "$VERBOSE" ]; then echo "$CMD0"; fi + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok else - $PRINTF "$FAILED\n" + $PRINTF "$FAILED (no stats)\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + echo "$CMD1" + cat "${te}1" >&2 + failed fi fi # NUMCOND ;; @@ -16533,16 +15890,13 @@ TEST="$NAME: test the children-shutup option" if ! eval $NUMCOND; then :; elif ! F=$(testfeats UNIX LISTEN EXEC FILE); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs UNIX-LISTEN TCP4 FILE UNIX-CONNECT); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions fork children-shutup) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport tcp4 ts="$td/test$N.sock" @@ -16560,23 +15914,20 @@ waitunixport $ts 1 rc1=$? kill $pid0 2>/dev/null; wait relsleep 1 # child process might need more time -if grep -q " W connect" ${te}0; then +if ! grep -q " E " ${te}0; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -16596,28 +15947,22 @@ TEST="$NAME: INTERFACE ignores outgoing packets" if ! eval $NUMCOND; then :; elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! $(type ping >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}ping not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testfeats TUN STDIO INTERFACE); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs - TUN STDIO INTERFACE); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions iff-up tun-type tun-name ) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -16650,8 +15995,7 @@ if [ $? -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif test -s "${tf}1"; then $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -16660,8 +16004,7 @@ elif test -s "${tf}1"; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -16670,12 +16013,10 @@ else if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac -PORT=$((PORT+1)) N=$((N+1)) @@ -16691,20 +16032,16 @@ TEST="$NAME: test if option reuseaddr's default is 1" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO PIPE IP4 TCP LISTEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO PIPE TCP4 TCP4-LISTEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions accept-timeout) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -16731,8 +16068,7 @@ if [ $rc0b -eq 0 ]; then if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD0b"; fi if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0a &" @@ -16741,9 +16077,7 @@ else cat "${te}1" >&2 echo "$CMD0b" cat "${te}0b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -16762,20 +16096,16 @@ TEST="$NAME: test if option reuseaddr's default is 1 with SSL-L" if ! eval $NUMCOND; then :; elif ! F=$(testfeats PIPE IP6 TCP OPENSSL LISTEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs PIPE OPENSSL-CONNECT OPENSSL-LISTEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions verify cert key) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -16806,8 +16136,7 @@ if [ $rc0b -eq 0 ]; then if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD0b"; fi if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0a &" @@ -16816,9 +16145,7 @@ else cat "${te}1" >&2 echo "$CMD0b" cat "${te}0b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -16837,20 +16164,16 @@ TEST="$NAME: test option reuseaddr without value" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO PIPE IP4 TCP LISTEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO PIPE TCP4-CONNECT TCP4-LISTEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions so-reuseaddr accept-timeout) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -16877,8 +16200,7 @@ if [ $rc0b -eq 1 ] && grep -q -e "Address already in use" -e "Address in use" "$ if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD0b"; fi if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok #elif grep -q "accept: \(Connection\|Operation\) timed out" "${te}0b"; then elif grep -q "accept: .* timed out" "${te}0b"; then # FreeBSD, Solaris do not seem to need SO_REUSEADDR with TCP at all @@ -16889,8 +16211,7 @@ elif grep -q "accept: .* timed out" "${te}0b"; then if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD0b"; fi if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else $PRINTF "$FAILED\n" echo "$CMD0a &" @@ -16899,9 +16220,7 @@ else cat "${te}1" >&2 echo "$CMD0b" cat "${te}0b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -16922,40 +16241,26 @@ TEST="$NAME: try all available TCP4 addresses" # that is closed on both addresses. # The test succeeded when the log shows that Socat tried to connect two times. if ! eval $NUMCOND; then :; -elif ! $(type nslookup >/dev/null 2>&1); then - $PRINTF "test $F_n $TEST... ${YELLOW}nslookup not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -#elif ! $(type nslookup >/dev/null 2>&1) && ! $(type host >/dev/null 2>&1); then -# $PRINTF "test $F_n $TEST... ${YELLOW}nslookup and host not available${NORMAL}\n" $N -# numCANT=$((numCANT+1)) -# listCANT="$listCANT $N" elif ! F=$(testfeats IP4 TCP GOPEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs TCP4-CONNECT GOPEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ -z "$INTERNET" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant +elif [ -z "$HAVEDNS" ]; then + $PRINTF "test $F_n $TEST... ${YELLOW}Broken DNS${NORMAL}\n" $N + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" -if type nslookup >/dev/null 2>&1; then - ADDRS=$(nslookup server-4.dest-unreach.net. |sed -n '/^$/,$ p' |grep ^Address |awk '{print($2);}') -elif type host >/dev/null 2>&1; then - ADDRS=$(host server-4.dest-unreach.net. |sed 's/.*address //') -fi while true; do newport tcp4 OPEN= @@ -16979,15 +16284,12 @@ if [ $(grep " N opening connection to .*AF=2 " ${te} |wc -l) -eq 2 ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD"; fi if [ "$DEBUG" ]; then cat "${te}" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD" cat "${te}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -17006,34 +16308,27 @@ TEST="$NAME: for TCP try all available IPv4 and IPv6 addresses" # neither IPv4 nor IPv6 # Check the log if Socat tried both addresses if ! eval $NUMCOND; then :; -#elif ! $(type nslookup >/dev/null 2>&1) && ! $(type host >/dev/null 2>&1); then -# $PRINTF "test $F_n $TEST... ${YELLOW}nslookup and host not available${NORMAL}\n" $N -# numCANT=$((numCANT+1)) -# listCANT="$listCANT $N" elif ! F=$(testfeats IP4 IP6 TCP); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs TCP-CONNECT GOPEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions ai-addrconfig) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available or not routable${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif [ -z "$INTERNET" ]; then # only needs Internet DNS + cant +elif [ -z "$INTERNET" -a "$RES" != 'DEVTESTS' ]; then $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant +elif [ -z "$HAVEDNS" ] && ! testfeats DEVTESTS >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}Broken DNS${NORMAL}\n" $N + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -17081,15 +16376,12 @@ if [ $(grep " N opening connection to .*AF=[0-9]" ${te} |wc -l) -eq 2 ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD"; fi if [ "$DEBUG" ]; then cat "${te}" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD" cat "${te}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -17109,32 +16401,25 @@ TEST="$NAME: option netns (net namespace $ns)" if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}Must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! $(type ip >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}ip program not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats IP4 TCP LISTEN NAMESPACES); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO TCP-LISTEN TCP EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions netns) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -17166,9 +16451,7 @@ if [ $rc1 -ne 0 ]; then echo "$CMD1" cat "${te}1" >&2 echo "ip netns del $ns" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif echo "$da" |od -c |diff - ${tf}1 >"$tdiff"; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then @@ -17182,8 +16465,7 @@ elif echo "$da" |od -c |diff - ${tf}1 >"$tdiff"; then if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "ip netns del $ns"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED (bad output)\n" echo "$CMD0 &" @@ -17192,9 +16474,7 @@ else cat "${te}1" >&2 diff: cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -17216,32 +16496,25 @@ TEST="$NAME: option netns with EXEC (net namespace $ns)" if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}Must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! $(type ip >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}ip program not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats IP4 ABSTRACT_UNIXSOCKET UDP LISTEN NAMESPACES STDIO); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs ABSTRACT-RECV ABSTRACT-SENDTO CREATE EXEC UDP4-RECV STDIO UDP4); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions netns) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -17274,9 +16547,7 @@ if [ $rc1 -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif echo "$da" |diff - ${tf}0 >"$tdiff" 2>/dev/null; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -17285,8 +16556,7 @@ elif echo "$da" |diff - ${tf}0 >"$tdiff" 2>/dev/null; then if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED (bad output)\n" echo "$CMD0 &" @@ -17297,9 +16567,7 @@ else cat "${te}2" >&2 echo diff: cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -17320,11 +16588,9 @@ if ! cond=$(checkconds \ "" \ "" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else - testecho "$N" "$TEST" "STDIO" "SOCKETPAIR" "$opts" + testecho "$N" "$NAME" "$TEST" "STDIO" "SOCKETPAIR" "$opts" fi esac N=$((N+1)) @@ -17342,11 +16608,9 @@ if ! cond=$(checkconds \ "" \ "" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else - testecho "$N" "$TEST" "STDIO" "SOCKETPAIR,socktype=2" "$opts" + testecho "$N" "$NAME" "$TEST" "STDIO" "SOCKETPAIR,socktype=2" "$opts" fi esac N=$((N+1)) @@ -17364,11 +16628,9 @@ if ! cond=$(checkconds \ "" \ "" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else - testecho "$N" "$TEST" "STDIO" "SOCKETPAIR,socktype=$SOCK_SEQPACKET" "$opts" + testecho "$N" "$NAME" "$TEST" "STDIO" "SOCKETPAIR,socktype=$SOCK_SEQPACKET" "$opts" fi esac N=$((N+1)) @@ -17386,26 +16648,22 @@ TEST="$NAME: Internal socketpair keeps packet boundaries" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO IP4 UDP SOCKETPAIR); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs - STDIO UDP4-DATAGRAM SOCKETPAIR); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions bind socktype ) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -ts1p=$PORT; PORT=$((PORT+1)) -ts2p=$PORT; PORT=$((PORT+1)) +newport udp; ts1p=$PORT +newport udp; ts2p=$PORT da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts -T 0.2 UDP4-DATAGRAM:$LOCALHOST:$ts2p,bind=$LOCALHOST:$ts1p SOCKETPAIR,socktype=$SOCK_DGRAM" CMD2="$TRACE $SOCAT $opts -b 24 -t 0.2 -T 0.3 - UDP4-DATAGRAM:$LOCALHOST:$ts1p,bind=$LOCALHOST:$ts2p" @@ -17424,8 +16682,7 @@ if [ "$rc2" -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD1 &" @@ -17434,21 +16691,18 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}2" >&2 echo diff: cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2 &"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) @@ -17463,20 +16717,16 @@ TEST="$NAME: ACCEPT-FD address" if ! eval $NUMCOND; then :; elif ! $(type systemd-socket-activate >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}systemd-socket-activate not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats IP4 TCP LISTEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs ACCEPT-FD PIPE STDIO TCP4); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -17498,8 +16748,7 @@ if echo "$da" |diff "${tf}1" - >$tdiff; then if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -17507,9 +16756,7 @@ else echo "$CMD1" cat "${te}1" >&2 cat $tdiff >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -17517,42 +16764,28 @@ esac N=$((N+1)) - -# Test the POSIX MQ feature with continuous READ and priorization on Linux -NAME=LINUX_POSIXMQ_READ_PRIO +# Test the POSIX MQ feature with continuous READ and prioritization on Linux +NAME=POSIXMQ_READ_PRIO case "$TESTS" in *%$N%*|*%functions%*|*%socket%*|*%posixmq%*|*%$NAME%*) -TEST="$NAME: POSIX-MQ (Linux) with prio" +TEST="$NAME: POSIX-MQ with prio" # Run a client/sender that creates a POSIX-MQ and sends a normal message and # then a client/sender with a higher priority message. # Run a passive/listening/receiving/reading process and check if it receives # both messages and in the prioritized order if ! eval $NUMCOND; then :; -elif [ "$UNAME" != Linux ]; then - $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif ! F=$(testfeats POSIXMQ STDIO); then - $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-READ STDIO); then - $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif ! o=$(testoptions mq-prio unlink-early unlink-close) >/dev/null; then - $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" +elif ! cond=$(checkconds "" "" "" "POSIXMQ STDIO" "POSIXMQ-SEND POSIXMQ-READ STDIO" "mq-prio unlink-early unlink-close"); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" tq=/test$N -CMD0a="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq,mq-prio=0,unlink-early" -CMD0b="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq,mq-prio=1" -CMD1="$TRACE $SOCAT --experimental $opts -u POSIXMQ-READ:$tq,unlink-close STDIO" +CMD0a="$TRACE $SOCAT $opts -u STDIO POSIXMQ-SEND:$tq,mq-prio=0,unlink-early" +CMD0b="$TRACE $SOCAT $opts -u STDIO POSIXMQ-SEND:$tq,mq-prio=1" +CMD1="$TRACE $SOCAT $opts -u POSIXMQ-READ:$tq,unlink-close STDIO" printf "test $F_n $TEST... " $N echo "$da 0" |$CMD0a 2>"${te}0a" rc0a=$? @@ -17563,16 +16796,14 @@ pid1=$! relsleep 1 kill $pid1; wait if [ $rc0a -ne 0 -o $rc0b -ne 0 ]; then - $PRINTF "$FAILED\n" + $PRINTF "$FAILED (rc0a=$rc0a, rc0b=$rc0b)\n" echo "$CMD0a" cat "${te}0a" >&2 echo "$CMD0b" cat "${te}0b" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif $ECHO "$da 1\n$da 0" |diff - ${tf}1 >${tdiff}1; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0a"; fi @@ -17581,10 +16812,9 @@ elif $ECHO "$da 1\n$da 0" |diff - ${tf}1 >${tdiff}1; then if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else - $PRINTF "$FAILED\n" + $PRINTF "$FAILED (diff)\n" echo "$CMD0a" cat "${te}0a" >&2 echo "$CMD0b" @@ -17593,50 +16823,35 @@ else cat "${te}1" >&2 echo "difference:" >&2 cat ${tdiff}1 >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; esac N=$((N+1)) -# Test the POSIX MQ feature with RECV,fork on Linux -NAME=LINUX_POSIXMQ_RECV_FORK +# Test the POSIX MQ feature with RECV,fork +NAME=POSIXMQ_RECV_FORK case "$TESTS" in *%$N%*|*%functions%*|*%fork%*|*%socket%*|*%posixmq%*|*%$NAME%*) -TEST="$NAME: POSIX-MQ (Linux) RECV with fork" +TEST="$NAME: POSIX-MQ RECV with fork" # Start a POSIX-MQ receiver with fork that creates a POSIX-MQ and stores its # output. # Run two clients/senders each with a message. # Check if both messages are stored. if ! eval $NUMCOND; then :; -elif [ "$UNAME" != Linux ]; then - $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif ! F=$(testfeats POSIXMQ STDIO); then - $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-RECEIVE STDIO); then - $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif ! o=$(testoptions fork unlink-early unlink-close) >/dev/null; then - $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" +elif ! cond=$(checkconds "" "" "" "POSIXMQ STDIO" "POSIXMQ-SEND POSIXMQ-READ STDIO" "fork unlink-early unlink-close"); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" tq=/test$N -CMD0="$TRACE $SOCAT --experimental $opts -u POSIXMQ-RECV:$tq,unlink-early,fork STDIO" -CMD1a="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq" -CMD1b="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq,unlink-close" +CMD0="$TRACE $SOCAT $opts -u POSIXMQ-RECV:$tq,unlink-early,fork STDIO" +CMD1a="$TRACE $SOCAT $opts -u STDIO POSIXMQ-SEND:$tq" +CMD1b="$TRACE $SOCAT $opts -u STDIO POSIXMQ-SEND:$tq,unlink-close" printf "test $F_n $TEST... " $N $CMD0 2>"${te}0" >"${tf}0" & pid0=$! @@ -17648,16 +16863,14 @@ rc1b=$? relsleep 1 kill $pid0; wait if [ $rc1a -ne 0 -o $rc1b -ne 0 ]; then - $PRINTF "$FAILED\n" + $PRINTF "$FAILED (rc1a=$rc1a, rc1b=$rc1b)\n" echo "$CMD0" cat "${te}0" >&2 echo "$CMD1a" cat "${te}1a" >&2 echo "$CMD1b" cat "${te}1b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif $ECHO "$da 0\n$da 1" |diff - ${tf}0 >${tdiff}0; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0"; fi @@ -17666,10 +16879,9 @@ elif $ECHO "$da 0\n$da 1" |diff - ${tf}0 >${tdiff}0; then if [ "$DEBUG" ]; then cat "${te}1a" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1b"; fi if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else - $PRINTF "$FAILED\n" + $PRINTF "$FAILED (diff)\n" echo "$CMD0" cat "${te}0" >&2 echo "$CMD1a" @@ -17678,77 +16890,66 @@ else cat "${te}1b" >&2 echo "difference:" >&2 cat ${tdiff}0 >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; esac N=$((N+1)) -# Test the POSIX MQ feature with RECV,fork,max-children on Linux -NAME=LINUX_POSIXMQ_RECV_MAXCHILDREN +# Test the POSIX MQ feature with RECV,fork,max-children +NAME=POSIXMQ_RECV_MAXCHILDREN case "$TESTS" in *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%socket%*|*%posixmq%*|*%$NAME%*) -TEST="$NAME: POSIX-MQ (Linux) RECV with fork,max-children" +TEST="$NAME: POSIX-MQ RECV with fork,max-children" # Start a POSIX-MQ receiver with fork that creates a POSIX-MQ and stores its -# output via sub processes that sleeps after writing. +# output via sub processes that sleep after writing. # Run a client/sender that sends message 1; -# run a client/sender that sends message 3, has to wait; -# write message 2 directly into output file; +# run a client/sender that sends message 2; +# run a client/sender that sends message 4, has to wait; +# write message 3 directly into output file; # Check if the messages are stored in order of their numbers if ! eval $NUMCOND; then :; -elif [ "$UNAME" != Linux ]; then - $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif ! F=$(testfeats POSIXMQ STDIO SYSTEM); then - $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-RECEIVE STDIO SYSTEM); then - $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif ! o=$(testoptions fork max-children unlink-early unlink-close) >/dev/null; then - $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" +elif ! cond=$(checkconds "" "" "" "POSIXMQ STDIO SHELL" "POSIXMQ-SEND POSIXMQ-RECEIVE STDIO SHELL" "fork max-children unlink-early unlink-close"); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" tq=/test$N -CMD0="$TRACE $SOCAT --experimental $opts -u POSIXMQ-RECV:$tq,unlink-early,fork,max-children=1 SYSTEM:\"cat\ >>${tf}0;\ sleep\ 1\"" -CMD1a="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq" -CMD1b="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq,unlink-close" +CMD0="$TRACE $SOCAT $opts -u POSIXMQ-RECV:$tq,unlink-early,fork,max-children=2 SHELL:\"cat\ >>${tf}0;\ relsleep\ 5\"" +CMD1a="$TRACE $SOCAT $opts -u STDIO POSIXMQ-SEND:$tq" +CMD1b="$TRACE $SOCAT $opts -u STDIO POSIXMQ-SEND:$tq,unlink-close" printf "test $F_n $TEST... " $N eval $CMD0 2>"${te}0" >"${tf}0" & pid0=$! relsleep 1 echo "$da 1" |$CMD1a >/dev/null 2>"${te}1a" rc1a=$? -echo "$da 3" |$CMD1b >/dev/null 2>"${te}1b" +echo "$da 2" |$CMD1a >/dev/null 2>"${te}1b" rc1b=$? -sleep 0.5 -echo "$da 2" >>"${tf}0" -sleep 1 # as in SYSTEM +echo "$da 4" |$CMD1b >/dev/null 2>"${te}1c" +rc1c=$? +#sleep 0.5 +relsleep 2 +echo "$da 3" >>"${tf}0" +relsleep 5 # as in SHELL kill $(childpids $pid0) $pid0 2>/dev/null wait 2>/dev/null if [ $rc1a -ne 0 -o $rc1b -ne 0 ]; then - $PRINTF "$FAILED\n" + $PRINTF "$FAILED (rc1a=$rc1a, rc1b=$rc1b, rc1c=$rc1c)\n" echo "$CMD0" cat "${te}0" >&2 echo "$CMD1a" cat "${te}1a" >&2 echo "$CMD1b" cat "${te}1b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" -elif $ECHO "$da 1\n$da 2\n$da 3" |diff - ${tf}0 >${tdiff}0; then + echo "$CMD1c" + cat "${te}1c" >&2 + failed +elif $ECHO "$da 1\n$da 2\n$da 3\n$da 4" |diff - ${tf}0 >${tdiff}0; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi @@ -17756,103 +16957,91 @@ elif $ECHO "$da 1\n$da 2\n$da 3" |diff - ${tf}0 >${tdiff}0; then if [ "$DEBUG" ]; then cat "${te}1a" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1b"; fi if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + if [ "$VERBOSE" ]; then echo "$CMD1c"; fi + if [ "$DEBUG" ]; then cat "${te}1c" >&2; fi + ok else - $PRINTF "$FAILED\n" + $PRINTF "$FAILED (diff)\n" echo "$CMD0" cat "${te}0" >&2 echo "$CMD1a" cat "${te}1a" >&2 echo "$CMD1b" cat "${te}1b" >&2 - echo "difference:" >&2 + echo "$CMD1c" + cat "${te}1c" >&2 + echo "// diff:" >&2 cat ${tdiff}0 >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; esac N=$((N+1)) -# Test the POSIX MQ feature with SEND,fork,max-children on Linux -NAME=LINUX_POSIXMQ_SEND_MAXCHILDREN +# Test the POSIX MQ feature with SEND,fork,max-children +NAME=POSIXMQ_SEND_MAXCHILDREN case "$TESTS" in *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%socket%*|*%posixmq%*|*%$NAME%*) -TEST="$NAME: POSIX-MQ (Linux) SEND with fork,max-children" -# Start a POSIX-MQ receiver that creates a POSIX-MQ and transfers data from -# there to an output file -# Run a POSIX-MQ sender that two times forks and invokes a data generator -# for messages 1 and 3 in a shell process with some trailing sleep. -# Afterwards write message 2 directly into output file; message 3 should be +TEST="$NAME: POSIX-MQ SEND with fork,max-children" +# Start a POSIX-MQ receiver that creates the MQ and transfers data from it +# to an output file +# Run a POSIX-MQ sender that forks two child shell processes that get data from +# a file queue with messages 1, 2, and 4, transfer it to the receiver and sleep +# afterwards to delay the third child by option max-children=2 +# Afterwards write message 3 directly into output file; message 4 should be # delayed due to max-children option # Check if the messages are stored in order of their numbers. -# The data generator is implemented as a receiver from an MQ with "1", "3" +# The data generator is implemented with just a directory containing files +# "1", "2", "4" if ! eval $NUMCOND; then :; -elif [ "$UNAME" != Linux ]; then - $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif ! F=$(testfeats POSIXMQ STDIO SYSTEM); then - $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-READ STDIO SYSTEM); then - $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif ! o=$(testoptions fork max-children mq-prio unlink-early unlink-close) >/dev/null; then - $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -#elif ! runsposixmq >/dev/null; then -# $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N -# numCANT=$((numCANT+1)) -# listCANT="$listCANT $N" +elif ! cond=$(checkconds "" "" "" "POSIXMQ STDIO SHELL" "POSIXMQ-SEND POSIXMQ-READ STDIO SHELL" "fork max-children mq-prio unlink-early unlink-close"); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" +tq="/test$N" +tQ="$td/test$N.q" da="test$N $(date) $RANDOM" -tq=/test$N -CMD0="$TRACE $SOCAT --experimental $opts -u POSIXMQ-READ:$tq,unlink-early STDIO" -CMD1="$TRACE $SOCAT --experimental $opts -U POSIXMQ-SEND:$tq,fork,max-children=1,interval=0.1 SYSTEM:\"./socat\ --experimental\ -u\ POSIXMQ-RECV\:$tq-data\ -;\ sleep\ 1\"" +CMD1="$TRACE $SOCAT $opts -lp reader -u POSIXMQ-READ:$tq,unlink-early STDIO" +#CMD2="$TRACE $SOCAT $opts -lp worker -U POSIXMQ-SEND:$tq,fork,max-children=2,interval=$(relsecs 2) SHELL:'f=\$(ls -1 $tQ|head -n 1);\ test\ -f\ "$tQ/\$f"\ ||\ exit\ 1;\ {\ cat\ $tQ/\$f;\ rm\ $tQ/\$f;\ };\ sleep\ $(relsecs 5)'" +CMD2="$TRACE $SOCAT $opts -lp worker -U POSIXMQ-SEND:$tq,fork,max-children=2,interval=$(relsecs 2) SHELL:'shopt\ -s\ nullglob;\ f=\$(ls -1 $tQ|head -n 1);\ test\ -z\ "\$f"\ &&\ exit;\ {\ cat\ $tQ/\$f;\ rm\ $tQ/\$f;\ };\ sleep\ $(relsecs 5)'" printf "test $F_n $TEST... " $N # create data for the generator -echo "$da 1" |$SOCAT -u --experimental - POSIXMQ-SEND:$tq-data,unlink-early -echo "$da 3" |$SOCAT -u --experimental - POSIXMQ-SEND:$tq-data -eval $CMD0 2>"${te}0" >>"${tf}0" & -pid0=$! -relsleep 1 -eval $CMD1 2>"${te}1" & +mkdir -p $tQ +echo "$da 1" >$tQ/01 +echo "$da 2" >$tQ/02 +echo "$da 4" >$tQ/04 +eval $CMD1 2>"${te}1" >>"${tf}1" & pid1=$! -sleep 0.5 -echo "$da 2" >>"${tf}0" -sleep 1 # as in SYSTEM -kill $pid0 $(childpids $pid0) $pid1 $(childpids $pid1) 2>/dev/null +relsleep 1 +eval $CMD2 2>"${te}2" & +pid2=$! +relsleep 4 +echo "$da 3" >>"${tf}1" +relsleep 10 +kill $(childpids -r $pid1) $pid1 $(childpids -r $pid2) $pid2 2>/dev/null wait 2>/dev/null -$SOCAT -u --experimental /dev/null POSIXMQ-SEND:$tq-data,unlink-close -if $ECHO "$da 1\n$da 2\n$da 3" |diff - ${tf}0 >${tdiff}0; then +# remove the MQ +$SOCAT -u /dev/null POSIXMQ-SEND:$tq,unlink-close 2>"${te}3b" +if $ECHO "$da 1\n$da 2\n$da 3\n$da 4" |diff - ${tf}1 >${tdiff}1; then $PRINTF "$OK\n" - if [ "$VERBOSE" ]; then echo "$CMD0"; fi - if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + if [ "$VERBOSE" ]; then echo "$CMD2"; fi + if [ "$DEBUG" ]; then cat "${te}2" >&2; fi + ok else $PRINTF "$FAILED\n" - echo "$CMD0" - cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - echo "difference:" >&2 - cat ${tdiff}0 >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + echo "$CMD2" + cat "${te}2" >&2 + echo "// diff:" >&2 + cat ${tdiff}1 >&2 + failed fi fi # NUMCOND ;; @@ -17871,16 +17060,13 @@ TEST="$NAME: sigint option with SHELL" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO SHELL PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO SHELL PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions setsid sigint) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -17901,15 +17087,12 @@ if grep -q " W waitpid..: child .* exited with status 130" "${te}0" || $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -17926,14 +17109,12 @@ TEST="$NAME: simple echo via SHELL of cat with socketpair" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO SHELL); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO SHELL); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else - testecho "$N" "$TEST" "" "SHELL:$CAT" "$opts" "$val_t" + testecho "$N" "$NAME" "$TEST" "" "SHELL:$CAT" "$opts" "$val_t" fi esac N=$((N+1)) @@ -17947,14 +17128,12 @@ TEST="$NAME: simple echo via SHELL of cat with pipes" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO SHELL SOCKETPAIR); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO SHELL PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else - testecho "$N" "$TEST" "" "SHELL:$CAT,pipes" "$opts" "$val_t" + testecho "$N" "$NAME" "$TEST" "" "SHELL:$CAT,pipes" "$opts" "$val_t" fi esac N=$((N+1)) @@ -17968,19 +17147,16 @@ TEST="$NAME: simple echo via SHELL of cat with pty" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO SHELL PTY); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO SHELL PTY); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ "$SHELL" = /bin/ksh ]; then # on NetBSD-9.3 this test kills test.sh script... $PRINTF "test $F_n $TEST... ${YELLOW}/bin/ksh might kill test.sh${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else - testecho "$N" "$TEST" "" "SHELL:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts" "$val_t" + testecho "$N" "$NAME" "$TEST" "" "SHELL:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts" "$val_t" fi esac N=$((N+1)) @@ -17994,14 +17170,12 @@ TEST="$NAME: call od -c via SHELL using socketpair" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO SHELL); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO SHELL); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else - testod "$N" "$TEST" "" "SHELL:$OD_C" "$opts" "$val_t" + testod "$N" "$NAME" "$TEST" "" "SHELL:$OD_C" "$opts" "$val_t" fi esac N=$((N+1)) @@ -18015,14 +17189,12 @@ TEST="$NAME: call od -c via SHELL using pipes" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO SHELL SOCKETPAIR); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO SHELL PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else - testod "$N" "$TEST" "" "SHELL:$OD_C,pipes" "$opts" "$val_t" + testod "$N" "$NAME" "$TEST" "" "SHELL:$OD_C,pipes" "$opts" "$val_t" fi esac N=$((N+1)) @@ -18042,29 +17214,24 @@ elif [ "$UNAME" = "NetBSD" ]; then # On NetBSD-4.0 and NetBSD-9.3 this test hangs (signal has no effect) # (other versions not tried) $PRINTF "test $F_n $TEST... ${YELLOW}might hang on $UNAME${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats SYCLS STDIO SYSTEM SOCKETPAIR); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO SYSTEM SOCKETPAIR); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions setsid sigint) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" #CMD0="$TRACE $SOCAT $opts PIPE SYSTEM:\"$SOCAT\ -dddd\ -lf ${te}1\ PIPE\ PIPE\",setsid,sigint" -# -T is required on (only?) OpenBSD-4 -CMD0="$TRACE $SOCAT $opts -T 2 SOCKETPAIR SYSTEM:\"$SOCAT\ -dddd\ -lf\ ${te}1\ PIPE\ PIPE\",setsid,sigint" -#CMD0="$TRACE $SOCAT $opts -T 2 SOCKETPAIR SYSTEM:\"$SOCAT\ -dddd\ -T\ 1\ -lf ${te}1\ PIPE\ PIPE\",setsid,sigint" +# Without -T process remains on OpenBSD-4, AIX, ? +CMD0="$TRACE $SOCAT $opts -T 2 SOCKETPAIR SYSTEM:\"$SOCAT\ -dddd\ -T\ 1\ -lf ${te}1\ PIPE\ PIPE\",setsid,sigint" printf "test $F_n $TEST... " $N eval $CMD0 >/dev/null 2>"${te}0" & pid0=$! @@ -18077,15 +17244,12 @@ if grep -q " W waitpid..: child .* exited with status 130" "${te}0"; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else - $PRINTF "${YELLOW}FAILED (shell does not propagate SIGINT?${NORMAL}\n" + $PRINTF "${YELLOW}FAILED (shell does not propagate SIGINT?)${NORMAL}\n" echo "$CMD0 &" cat "${te}0" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant fi fi # NUMCOND ;; @@ -18105,20 +17269,16 @@ TEST="$NAME: test the res-nsaddr option" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO IP4 UDP TCP); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO TCP4 UDP-RECVFROM); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions res-nsaddr) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available on host${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -18141,26 +17301,21 @@ if grep "$da" "${tf}0" >/dev/null; then if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok elif pgrep -u root nscd >/dev/null 2>&1; then $PRINTF "${YELLOW}FAILED (due to nscd?)${NORMAL}\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCAnT="$namesCANT $NAME" + cant else $PRINTF "$FAILED (query not received)\n" echo "$CMD0 &" cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -18189,16 +17344,13 @@ TEST="$NAME: restore of pwd after CREAT with chdir option" if ! eval $NUMCOND; then :; elif ! F=$(testfeats CREAT SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs - CREAT SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions chdir) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -18223,31 +17375,24 @@ else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif [ "$tpwd" != "$td" ]; then $PRINTF "$FAILED (chdir failed)\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! echo "$pwd2" |diff "$td/$tc" - >$tdiff; then $PRINTF "$FAILED (bad pwd2)\n" echo "$CMD0 &" cat "${te}0" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -18267,16 +17412,13 @@ TEST="$NAME: restore of pwd after SYSTEM with chdir option" if ! eval $NUMCOND; then :; elif ! F=$(testfeats SHELL SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs SHELL SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions chdir) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -18302,31 +17444,24 @@ else $PRINTF "$FAILED (rc=$rc0)\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif [ "$tpwd" != "$td" ]; then $PRINTF "$FAILED (chdir failed)\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! echo "$pwd2" |diff "$td/$tc" - >$tdiff; then $PRINTF "$FAILED (bad pwd)\n" echo "$CMD0 &" cat "${te}0" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -18347,16 +17482,13 @@ TEST="$NAME: test restore after CREAT with umask option" if ! eval $NUMCOND; then :; elif ! F=$(testfeats CREAT SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs CREAT SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions umask) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -18386,30 +17518,23 @@ else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif [ $((tumask + tperms - 0666)) -ne 0 ]; then $PRINTF "$FAILED (umask failed)\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! [ "$oumask" -eq $(cat "$tc") ]; then $PRINTF "$FAILED (bad umask)\n" echo "$CMD0 &" cat "${te}0" >&2 cat "$tdebug" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -18429,16 +17554,13 @@ TEST="$NAME: test restore after SHELL with umask option" if ! eval $NUMCOND; then :; elif ! F=$(testfeats SHELL SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs SHELL SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions umask) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -18468,30 +17590,23 @@ else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif [ $((tumask + tperms - 0666)) -ne 0 ]; then $PRINTF "$FAILED (umask failed)\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! [ "$oumask" -eq $(cat "$tc") ]; then $PRINTF "$FAILED (bad umask)\n" echo "$CMD0 &" cat "${te}0" >&2 cat "$tdebug" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -18519,14 +17634,13 @@ TEST="$NAME: Option unix-bind-tempname" # log "Transport endpoint is not connected" and the TCP service does not fail # with "Address already in use"), the test succeeded. if ! eval $NUMCOND; then :; -elif [[ $CLI_ =~ ABSTRACT-* ]] && ! feat=$(testfeats abstract-unixsocket); then +#elif [[ $CLI_ =~ ABSTRACT-* ]] && ! feat=$(testfeats abstract-unixsocket); then +elif re_match "$CLI_" 'ABSTRACT-*' && ! feat=$(testfeats abstract-unixsocket); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions unix-bind-tempname) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ts="$td/test$N.sock" tf="$td/test$N.stdout" @@ -18544,7 +17658,7 @@ CMD0="$TRACE $SOCAT $opts -lp server $SRV:${ts}0,fork PIPE" # The following command is the solution: option unix-bind-tempname generates # random names (like tempnam(2)) for binding the datagram client socket; # creating the XXXXXX file makes sure that the (non abstract) clients cannot -# erronously bind there (part of the test) +# erroneously bind there (part of the test) CMD1="$TRACE $SOCAT $opts -lp bind-tempname TCP4-LISTEN:$PORT,reuseaddr,fork $CLI:${ts}0,bind=${ts}1" touch ${ts}1.XXXXXX; CMD1="$TRACE $SOCAT $opts -lp tempname TCP4-LISTEN:$PORT,reuseaddr,fork $CLI:${ts}0,bind-tempname=${ts}1.XXXXXX" CMD2="$TRACE $SOCAT $opts -lp client - TCP4-CONNECT:$LOCALHOST:$PORT" @@ -18572,8 +17686,7 @@ if [ $rc2b -ne 0 ]; then cat "${te}2a" >&2 echo "$CMD2" cat "${te}2b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da a" |diff - ${tf}2a >${tdiff}2a; then $PRINTF "$FAILED (phase a)\n" echo "$CMD0 &" @@ -18584,8 +17697,7 @@ elif ! echo "$da a" |diff - ${tf}2a >${tdiff}2a; then cat "${te}2a" >&2 echo "diff a:" >&2 cat ${tdiff}2a >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da b" |diff - ${tf}2b >${tdiff}2b; then $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -18598,8 +17710,7 @@ elif ! echo "$da b" |diff - ${tf}2b >${tdiff}2b; then cat "${te}2b" >&2 echo "diff b:" >&2 cat ${tdiff}2b >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -18610,13 +17721,11 @@ else if [ "$DEBUG" ]; then cat "${te}2a" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) done <<<" @@ -18668,8 +17777,7 @@ if [ -e $ts3 ]; then cat "${te}0b" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! grep -q " E " ${te}1; then $PRINTF "$FAILED\n" echo "Socat did not fail" @@ -18679,8 +17787,7 @@ elif ! grep -q " E " ${te}1; then cat "${te}0b" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0a"; fi @@ -18689,13 +17796,11 @@ else if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) @@ -18709,26 +17814,22 @@ TEST="$NAME: f-setpipe-sz on STDIN" if ! eval $NUMCOND; then :; elif ! $(type true >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}true not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats STDIO EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions f-setpipe-sz nofork) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" -newport tcp4 # or whatever proto, or drop this line +newport tcp4 # Find the default pipe size PIPESZ="$(echo |$FILAN -n 0 |grep "0:" |head -n 1 |sed 's/.*F_GETPIPE_SZ=\([0-9][0-9]*\).*/\1/')" PIPESZ2=$((2*PIPESZ)) @@ -18741,24 +17842,19 @@ if [ "$rc0" -ne 0 ]; then $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! diff <(echo $PIPESZ2) <(echo $PIPESZ2b) >$tdiff; then $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" >&2 echo "diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -18775,16 +17871,13 @@ TEST="$NAME: f-setpipe-sz on EXEC with pipes" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions pipes f-setpipe-sz) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -18801,24 +17894,19 @@ if [ "$rc0" -ne 0 ]; then $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! diff <(echo $PIPESZ2) <(echo $PIPESZ2b) >$tdiff; then $PRINTF "$FAILED\n" echo "$CMD0 &" cat "${te}0" >&2 echo "diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -18837,8 +17925,7 @@ elif ! cond=$(checkconds "" "" "" \ "so-reuseaddr" \ "dccp4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -18859,9 +17946,7 @@ if [ $? -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -18870,17 +17955,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid1 2>/dev/null wait @@ -18892,7 +17974,7 @@ N=$((N+1)) NAME=UDPLITE4STREAM case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udplite%*|*%$NAME%*) -TEST="$NAME: echo via connection to UDP-Lite V4 socket" +TEST="$NAME: echo via connection to UDP-Lite IPv4 socket" if ! eval $NUMCOND; then :; elif ! cond=$(checkconds \ "" \ @@ -18903,9 +17985,7 @@ elif ! cond=$(checkconds \ "so-reuseaddr" \ "udplite4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -18928,8 +18008,7 @@ else cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED (diff)\n" echo "$CMD1 &" >&2 @@ -18938,28 +18017,24 @@ else cat "${te}2" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac -PORT=$((PORT+1)) N=$((N+1)) NAME=UDPLITE4STREAM case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udplite%*|*%$NAME%*) -TEST="$NAME: echo via connection to UDP-Lite V4 socket" +TEST="$NAME: echo via connection to UDP-Lite IPv4 socket" if ! eval $NUMCOND; then :; elif ! cond=$(checkconds \ "" \ @@ -18970,9 +18045,7 @@ elif ! cond=$(checkconds \ "so-reuseaddr" \ "udplite4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -18995,8 +18068,7 @@ else cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED (diff)\n" echo "$CMD1 &" >&2 @@ -19005,54 +18077,48 @@ else cat "${te}2" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac -PORT=$((PORT+1)) N=$((N+1)) -NAME=UDPLITE4STREAM +NAME=UDPLITE6STREAM case "$TESTS" in -*%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udplite%*|*%$NAME%*) -TEST="$NAME: echo via connection to UDP-Lite V4 socket" +*%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%udplite%*|*%$NAME%*) +TEST="$NAME: echo via connection to UDP-Lite IPv6 socket" if ! eval $NUMCOND; then :; elif ! cond=$(checkconds \ "" \ "" \ "" \ - "IP4 UDPLITE LISTEN STDIO PIPE" \ - "UDPLITE4-LISTEN PIPE STDIO UDPLITE4" \ + "IP6 UDPLITE LISTEN STDIO PIPE" \ + "UDPLITE6-LISTEN PIPE STDIO UDPLITE6" \ "so-reuseaddr" \ - "udplite4" ); then + "udplite6" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT - ts="$LOCALHOST:$tsl" + ts="$LOCALHOST6:$tsl" da="test$N $(date) $RANDOM" - CMD1="$TRACE $SOCAT $opts UDPLITE4-LISTEN:$tsl,$REUSEADDR PIPE" - CMD2="$TRACE $SOCAT $opts - UDPLITE4:$ts" + CMD1="$TRACE $SOCAT $opts UDPLITE6-LISTEN:$tsl,$REUSEADDR PIPE" + CMD2="$TRACE $SOCAT $opts - UDPLITE6:$ts" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid1=$! - waitudplite4port $tsl 1 + waitudplite6port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" rc2=$? kill $pid1 2>/dev/null; wait @@ -19062,8 +18128,7 @@ else cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED (diff)\n" echo "$CMD1 &" >&2 @@ -19072,21 +18137,17 @@ else cat "${te}2" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac -PORT=$((PORT+1)) N=$((N+1)) @@ -19116,9 +18177,7 @@ elif ! cond=$(checkconds \ "$REUSEADDR bind" \ "$protov" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19156,8 +18215,7 @@ if [ $rc1 != 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ "$(grep SOCAT_SOCKADDR "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g")" = "$TEST_SOCKADDR" -a \ "$(grep SOCAT_PEERADDR "${tf}" |sed -e 's/^[^=]*=//' -e "s/[\"']//g")" = "$TEST_PEERADDR" -a \ \( "$PORTMETHOD" = ',' -o "$(grep SOCAT_SOCKPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$TEST_SOCKPORT" \) -a \ @@ -19170,8 +18228,7 @@ elif [ "$(grep SOCAT_SOCKADDR "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g" echo "$CMD1" cat "${te}1" fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -19180,8 +18237,7 @@ else cat "${te}1" echo -e "SOCAT_SOCKADDR=$TEST_SOCKADDR\nSOCAT_PEERADDR=$TEST_PEERADDR\nSOCAT_SOCKPORT=$TEST_SOCKPORT\nSOCAT_PEERPORT=$TEST_PEERPORT" | diff - "${tf}" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND, feats ;; @@ -19202,10 +18258,10 @@ RUNS=$(tolower $KEYW) PROTO=$KEYW proto="$(tolower "$PROTO")" # test the max-children option on pseudo connected sockets -NAME=${KEYW}MAXCHILDREN +NAME=${KEYW}_L_MAXCHILDREN case "$TESTS" in *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%$SEL%*|*%socket%*|*%listen%*|*%$NAME%*) -TEST="$NAME: max-children option" +TEST="$NAME: max-children option with $PROTO-LISTEN" # start a listen process with max-children=1; connect with a client, let it # send data and then sleep; connect with second client that wants to send # data immediately, but keep first client active until server terminates. @@ -19221,9 +18277,7 @@ elif ! cond=$(checkconds \ "$REUSEADDR o-trunc o-creat o-append fork max-children $SHUT" \ "$RUNS" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else case "X$IPPORT" in "XPORT") @@ -19257,8 +18311,7 @@ cpids="$(childpids $pid0)" kill $pid1 $pid2 $cpids $pid0 2>/dev/null; wait if echo -e "$da 1" |diff - $tf >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -19268,8 +18321,7 @@ else cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -19297,8 +18349,7 @@ elif ! cond=$(checkconds \ "" \ "" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19311,24 +18362,19 @@ else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! tty |diff - <(cat ${tf}0 |grep "controlling terminal" |grep -v -e '"/dev/tty"' -e none |head -n 1 |sed -e 's/controlling terminal by .*:[[:space:]]*//' -e 's/"//g') >$tdiff; then $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -19353,9 +18399,7 @@ elif ! cond=$(checkconds \ "so-reuseaddr" \ "tcp4 unix" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else ts="$td/test$N.sock" tf="$td/test$N.stdout" @@ -19378,9 +18422,7 @@ else cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! echo "$da" |diff - "${tf}1" >$tdiff; then $PRINTF "$FAILED (diff)\n" echo "$CMD0 &" @@ -19389,17 +18431,14 @@ else cat "${te}1" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -19424,14 +18463,10 @@ elif ! cond=$(checkconds \ "so-reuseaddr" \ "tcp4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" -elif [[ $BASH_VERSION =~ ^[1-3]\. ]]; then + cant +elif re_match "$BASH_VERSION" '^[1-3]\.'; then $PRINTF "test $F_n $TEST... ${YELLOW}requires bash 4 or higher${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else gentestcert testsrv tp="$td/test$N.pty" @@ -19456,9 +18491,7 @@ else cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! echo "$da" |diff - "${tf}1" >$tdiff; then $PRINTF "$FAILED (diff)\n" echo "$CMD0 &" @@ -19467,17 +18500,14 @@ else cat "${te}1" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -19505,9 +18535,7 @@ elif ! cond=$(checkconds \ "so-reuseaddr" \ "tcp4 unix" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19545,9 +18573,7 @@ else cat "${te}2a" >&2 echo "{ relsleep 20; echo \"\$da_b\"; relsleep 10; } |$CMD2" cat "${te}2b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! $ECHO "$da_a\n$da_b" |diff - "${tf}2a" >${tdiff}_a; then $PRINTF "$FAILED (diff a)\n" echo "$CMD0 &" @@ -19560,9 +18586,7 @@ else cat "${te}2b" >&2 echo "// diff a:" >&2 cat "${tdiff}_a" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! $ECHO "$da_a\n$da_b" |diff - "${tf}2b" >${tdiff}_b; then $PRINTF "$FAILED (diff b)\n" echo "$CMD0 &" @@ -19575,9 +18599,7 @@ else cat "${te}2b" >&2 echo "// diff b:" >&2 cat "${tdiff}_b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -19588,8 +18610,7 @@ else if [ "$DEBUG" ]; then cat "${te}2a" >&2; fi if [ "$VERBOSE" ]; then echo "{ relsleep 20; echo \"\$da_b\"; relsleep 10; } |$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -19616,9 +18637,7 @@ elif ! cond=$(checkconds \ "so-reuseaddr" \ "udp4 tcp4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19647,9 +18666,7 @@ else cat "${te}1a" >&2 echo "{ relsleep 20; echo \"\$da_b\"; relsleep 10; } |$CMD1" cat "${te}1b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! $ECHO "$da_a\n$da_b" |diff - "${tf}1a" >${tdiff}_a; then $PRINTF "$FAILED (diff a)\n" echo "$CMD0 &" @@ -19660,9 +18677,7 @@ else cat "${te}1b" >&2 echo "// diff a:" >&2 cat "${tdiff}_a" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! $ECHO "$da_a\n$da_b" |diff - "${tf}1b" >${tdiff}_b; then $PRINTF "$FAILED (diff b)\n" echo "$CMD0 &" @@ -19673,9 +18688,7 @@ else cat "${te}1b" >&2 echo "// diff b:" >&2 cat "${tdiff}_b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -19684,8 +18697,7 @@ else if [ "$DEBUG" ]; then cat "${te}1a" >&2; fi if [ "$VERBOSE" ]; then echo "{ relsleep 20; echo \"\$da_b\"; relsleep 10.; } |$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -19715,9 +18727,7 @@ elif ! cond=$(checkconds \ "fork" \ "udp4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19739,35 +18749,28 @@ else cat "${te}0" >&2 echo "echo \$da\" |$CMD1" cat "${te}1" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant elif [ $(grep -c " E open(" "${te}0") -eq 0 ]; then $PRINTF "$CANT (no error)\n" echo "$CMD0 &" cat "${te}0" >&2 echo "echo \$da\" |$CMD1" cat "${te}1" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant elif [ $(grep -c " E open(" "${te}0") -ge 2 ]; then $PRINTF "$FAILED (this bug)\n" echo "$CMD0 &" head -n 2 "${te}0" >&2 echo "echo \$da\" |$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -19795,9 +18798,7 @@ elif ! cond=$(checkconds \ "fork" \ "udp4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19822,9 +18823,7 @@ else cat "${te}1a" >&2 echo "echo \$da b\" |$CMD1" cat "${te}1b" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant elif [ $(grep -c " I socketpair(" "${te}0") -ne 2 ]; then $PRINTF "$CANT (not 2 socketpair())\n" echo "$CMD0 &" @@ -19833,9 +18832,7 @@ else cat "${te}1a" >&2 echo "echo \$da b\" |$CMD1" cat "${te}1b" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant elif ! diff <(grep " I socketpair(" "${te}0" |head -n 1 |sed 's/.*\( I socketpair.*\)/\1/') <(grep " I socketpair(" "${te}0" |tail -n 1 |sed 's/.*\( I socketpair.*\)/\1/') >/dev/null 2>&1; then $PRINTF "$FAILED (this bug)\n" echo "$CMD0 &" @@ -19844,9 +18841,7 @@ else cat "${te}1a" >&2 echo "echo \$da b\" |$CMD1" cat "${te}1b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -19855,8 +18850,7 @@ else if [ "$DEBUG" ]; then cat "${te}1a" >&2; fi if [ "$VERBOSE" ]; then echo "echo \$da b\" |$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -19885,9 +18879,7 @@ elif ! cond=$(checkconds \ "pf" \ "ip4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19901,15 +18893,12 @@ else $PRINTF "$FAILED (rc0=$rc0)\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -19954,9 +18943,7 @@ TEST="$NAME: TCP-L with -0 accepts IPv4" if ! eval $NUMCOND; then : elif [ -z "$opt0" -a $SOCAT_VERSION != 1.8.0.0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}Option -0 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant elif ! cond=$(checkconds \ "" \ "" \ @@ -19966,9 +18953,7 @@ elif ! cond=$(checkconds \ "" \ "tcp4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else opt0= if SOCAT_MAIN_WAIT= $SOCAT -h |grep -e '[[:space:]]-0[[:space:]]' >/dev/null; then @@ -19996,21 +18981,17 @@ else if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) ;; + ok ;; Linux) $PRINTF "$FAILED (rc1=$rc1)\n" echo "$CMD0 &" cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" ;; + failed ;; *) $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" ;; + cant ;; esac else $PRINTF "$OK\n" @@ -20018,7 +18999,7 @@ else if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) + ok fi fi # NUMCOND ;; @@ -20035,21 +19016,17 @@ TEST="$NAME: TCP-L with -0 accepts IPv6" if ! eval $NUMCOND; then : elif [ -z "$opt0" -a $SOCAT_VERSION != 1.8.0.0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}Option -0 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant elif ! cond=$(checkconds \ "" \ "" \ "" \ "IP6 TCP LISTEN FILE" \ "TCP-LISTEN TCP6-CONNECT FILE" \ - "" \ + "ai-addrconfig" \ "tcp6" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -20071,23 +19048,20 @@ else cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) + ok fi fi # NUMCOND ;; esac N=$((N+1)) - BIN_TIMEOUT= if type timeout >/dev/null 2>&1; then BIN_TIMEOUT=timeout @@ -20124,9 +19098,7 @@ elif ! cond=$(checkconds \ "${option%%=*}" \ "$(tolower $PROTO)4 $(tolower $PROTO)6" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -20134,16 +19106,14 @@ else da="test$N $(date) $RANDOM" case X$IPPORT in XPORT) newport $(tolower $PROTO); _PORT=$PORT ;; - XPROTO) echo "IPPROTO=\"$IPPROTO\"" + XPROTO) #echo "IPPROTO=\"$IPPROTO\"" _PORT=$IPPROTO ;; esac CMD0="$TRACE $SOCAT $opts ${ADDR}:$_PORT,$option,$ACCEPT_TIMEOUT PIPE" printf "test $F_n $TEST... " $N if [ -z "$ACCEPT_TIMEOUT" ] && [ -z "$BIN_TIMEOUT" ]; then $PRINTF "$CANT (would block)\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else if [ "$BIN_TIMEOUT" ]; then $BIN_TIMEOUT 0.1 $CMD0 >/dev/null 2>"${te}0" @@ -20156,15 +19126,12 @@ else $PRINTF "$FAILED (rc0=$rc0)\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # not would block fi # NUMCOND @@ -20224,9 +19191,7 @@ elif ! cond=$(checkconds \ "bind" \ "$protov" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -20234,7 +19199,7 @@ else da="test$N $(date) $RANDOM" case X$IPPORT in XPORT) newport $(tolower $PROTO); _PORT=$PORT ;; - XPROTO) echo "IPPROTO=\"$IPPROTO\"" + XPROTO) #echo "IPPROTO=\"$IPPROTO\"" _PORT=$IPPROTO ;; esac CMD0="$TRACE $SOCAT $opts -u /dev/null $ADDR:localhost-6-4.dest-unreach.net:$_PORT,bind=127.0.0.1" @@ -20245,20 +19210,16 @@ else $PRINTF "$FAILED (rc0=$rc0)\n" echo "$CMD0" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) done <<<" UDP-SENDTO udp4 PORT @@ -20294,9 +19255,7 @@ elif ! cond=$(checkconds \ "bind" \ "$protov" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -20304,7 +19263,7 @@ else da="test$N $(date) $RANDOM" case X$IPPORT in XPORT) newport $(tolower $PROTO); _PORT=$PORT ;; - XPROTO) echo "IPPROTO=\"$IPPROTO\"" + XPROTO) #echo "IPPROTO=\"$IPPROTO\"" _PORT=$IPPROTO ;; esac CMD0="$TRACE $SOCAT $opts ${ADDR%%-*}-LISTEN:$_PORT,pf=ip4 PIPE" @@ -20322,20 +19281,16 @@ else cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) done <<<" TCP-CONNECT tcp4 PORT @@ -20349,6 +19304,10 @@ DCCP-CONNECT dccp4 PORT " +# Above tests introduced before or with 1.8.0.1 +#============================================================================== +# Below test introduced with 1.8.0.2 + # Test the readline.sh file overwrite vulnerability NAME=READLINE_SH_OVERWRITE case "$TESTS" in @@ -20367,9 +19326,7 @@ elif ! cond=$(checkconds \ "" \ "" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.file" te="$td/test$N.stderr" @@ -20385,9 +19342,7 @@ else # $PRINTF "$CANT (rc0=$rc0)\n" # echo "$CMD0" # cat "${te}0" >&2 -# numCANT=$((numCANT+1)) -# listCANT="$listCANT $N" -# namesCANT="$namesCANT $NAME" +# cant # elif ! echo "$da" |diff - "$tf" >$tdiff; then if ! echo "$da" |diff - "$tf" >$tdiff; then $PRINTF "$FAILED (diff)\n" @@ -20395,30 +19350,773 @@ else cat "${te}0" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; esac N=$((N+1)) + +# Above test introduced with 1.8.0.2 +#============================================================================== +# Below tests introduced with 1.8.0.3 (or later) + +# Test the SOCKS5-CONNECT and SOCKS5-LISTEN addresses with IPv4 +for SUFFIX in CONNECT LISTEN; do + +suffix=$(tolower $SUFFIX) +if [ "$SUFFIX" = LISTEN ]; then + test=listen + LISTEN=LISTEN + listen=listen +else + test=dont + LISTEN= + listen= +fi +NAME=SOCKS5${SUFFIX}_TCP4 +case "$TESTS" in +*%$N%*|*%functions%*|*%socks%*|*%socks5%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$test%*|*%$NAME%*) +TEST="$NAME: SOCKS5-$SUFFIX over TCP/IPv4" +if ! eval $NUMCOND; then :; +elif ! cond=$(checkconds \ + "" \ + "" \ + "od ./socks5server-echo.sh" \ + "SOCKS5 IP4 TCP $LISTEN STDIO" \ + "TCP4-LISTEN EXEC STDIN SOCKS5-$SUFFIX" \ + "so-reuseaddr readbytes" \ + "tcp4" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant +else + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" + newport tcp4 # provide free port number in $PORT + CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,$REUSEADDR EXEC:\"./socks5server-echo.sh\"" + CMD1="$TRACE $SOCAT $opts STDIO SOCKS5-$SUFFIX:$LOCALHOST:127.0.0.1:80,pf=ip4,socksport=$PORT" + printf "test $F_n $TEST... " $N + eval "$CMD0 2>\"${te}0\" &" + pid0=$! # background process id + waittcp4port $PORT 1 + echo "$da" |$CMD1 >${tf}1 2>"${te}1" + rc1=$? + kill $pid0 2>/dev/null + wait + if [ "$rc1" -ne 0 ]; then + $PRINTF "$FAILED (rc1=$rc1)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + failed + elif ! echo "$da" |diff - "${tf}1" >"$tdiff"; then + $PRINTF "$FAILED (diff)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + failed + else + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok + fi +fi ;; # NUMCOND, feats +esac +N=$((N+1)) + +done # CONNECT LISTEN + + +# Test UDP-LISTEN with bind to IPv4 address; this failed with Socat version +# 1.8.0.0 +NAME=UDP_LISTEN_BIND4 +case "$TESTS" in +*%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%ip4%*|*%udp%*|*%udp4%*|*%listen%*|*%$NAME%*) +TEST="$NAME: Test UDP-LISTEN with bind to IPv4 addr" +# Start a listener with UDP-LISTEN and bind to 127.0.0.1; when it starts +# without error and even processes data the test succeeded +if ! eval $NUMCOND; then : +# Remove unneeded checks, adapt lists of the remaining ones +elif ! cond=$(checkconds \ + "" \ + "" \ + "" \ + "IP4 UDP LISTEN STDIO PIPE" \ + "UDP-LISTEN PIPE STDIO UDP" \ + "bind" \ + "udp4" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant +else + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM" + newport udp4 + CMD0="$TRACE $SOCAT $opts UDP-LISTEN:$PORT,bind=$LOCALHOST4 PIPE" + CMD1="$TRACE $SOCAT $opts - UDP-CONNECT:$LOCALHOST4:$PORT" + printf "test $F_n $TEST... " $N + $CMD0 >/dev/null 2>"${te}0" & + pid0=$! + waitudp4port $PORT 1 + echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" + rc1=$? + kill $pid0 2>/dev/null; wait + if [ "$rc1" -ne 0 ]; then + $PRINTF "$FAILED (rc1=$rc1)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + failed + elif ! echo "$da" |diff - "${tf}1" >$tdiff; then + $PRINTF "$FAILED (diff)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + failed + else + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok + fi +fi # NUMCOND + ;; +esac +N=$((N+1)) + + +# Test for useful error message on UNIX-L with bind option +NAME=UNIX_L_BIND +case "$TESTS" in +*%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%listen%*|*%unix%*|*%bind%*|*%$NAME%*) +TEST="$NAME: Test if UNIX-L with bind does not fail INTERNAL" +# Invoke Socat with a UNIX-LISTEN address with bind option. +# When there is no INTERNAL error the test succeeded. +if ! eval $NUMCOND; then : +elif ! cond=$(checkconds \ + "" \ + "" \ + "" \ + "UNIX LISTEN PIPE" \ + "UNIX-LISTEN PIPE" \ + "bind,accept-timeout" \ + "" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant +else + ts="$td/test$N.sock" + tb="$td/test$N.bind" + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM" + CMD0="$TRACE $SOCAT $opts UNIX-LISTEN:$ts,accept-timeout=0.001,bind=$tb PIPE" + printf "test $F_n $TEST... " $N + $CMD0 >/dev/null 2>"${te}0" + rc0=$? + if [ "$rc0" -eq 0 ]; then + $PRINTF "$CANT (rc0=$rc0)\n" + echo "$CMD0" + cat "${te}0" >&2 + cant + elif grep " E .* INTERNAL " "${te}0" >/dev/null; then + $PRINTF "$FAILED (INTERNAL)\n" + echo "$CMD0" + cat "${te}0" >&2 + failed + else + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + ok + fi +fi # NUMCOND + ;; +esac +N=$((N+1)) + + +while read ADDR proto CSUFF CPARMS COPTS SADDR SOPTS PIPE; do +if [ -z "$ADDR" ] || [[ "$ADDR" == \#* ]]; then continue; fi + +if [ "X$CSUFF" != "X-" ]; then + CADDR=$ADDR-$CSUFF +else + CADDR=$ADDR +fi +CNAME=$(echo $CADDR |tr - _) +PROTO=$(toupper $proto) +FEAT=$ADDR +addr=$(tolower $ADDR) +runs=$proto +case "$CPARMS" in + PORT) newport $proto; CPARMS=$PORT ;; + *'$PORT'*) newport $proto; CPARMS=$(eval echo "$CPARMS") ;; +esac +#echo "PORT=$PORT CPARMS=$CPARMS" >&2 +case "X$COPTS" in + X-) COPTS= ;; + *'$PORT'*) newport $proto; COPTS=$(eval echo "$COPTS") ;; +esac +case "X$SOPTS" in + X-) SOPTS= ;; +esac + +# Test if bind on *-CONNECT selects the matching IP version +NAME=${CNAME}_BIND_6_4 +case "$TESTS" in +*%$N%*|*%functions%*|*%$addr%*|*%$proto%*|*%${proto}4%*|*%${proto}6%*|*%ip4%*|*%ip6%*|*%listen%*|*%bind%*|*%socket%*|*%$NAME%*) +TEST="$NAME: $ADDR bind chooses matching IPv" +# Have an IPv4 listener +# Host name localhost-4-6.dest-unreach.net resolves to both 127.0.0.1 and [::1], +# consequently; with option -6 we have Socat try IPv6 first, and on failure try +# IPv4 +# Start Socat TCP-CONNECT with -6 and binding and connecting to this host name; +# Up to version 1.8.0.0 Socat only tries IPv6 and fails +# With version 1.8.0.1 Socat first connects using IPv6, and due to ECONNREFUSED +# tries to connect using IPv4 but still binds to IPv6 which fails with +# EAFNOSUPPORT "Address family not supported by protocol"; +# With 1.8.0.3 the connection attempt with IPv4 correctly binds to IPv4 and +# succeeds +if ! eval $NUMCOND; then : +elif ! cond=$(checkconds \ + "" \ + "" \ + "" \ + "$FEAT IP4 IP6 TCP LISTEN STDIO PIPE" \ + "$CADDR $SADDR STDIO PIPE" \ + "bind pf" \ + "${runs}4 ${runs}6" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant +elif ! SOCAT_MAIN_WAIT= $SOCAT -h |grep -e '[[:space:]]-6[[:space:]]' >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}no option -0${NORMAL}\n" $N + cant +elif [ -z "$INTERNET" -a "$RES" != 'DEVTESTS' ]; then + $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N + cant +elif [ -z "$HAVEDNS" ] && ! testfeats DEVTESTS >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}Broken DNS${NORMAL}\n" $N + cant +else + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM" + CMD0="$TRACE $SOCAT $opts $SADDR:$PORT,$SOPTS,pf=2 $PIPE" + CMD1="$TRACE $SOCAT $opts -6 STDIO $CADDR:localhost-4-6.dest-unreach.net:$CPARMS,bind=localhost-4-6.dest-unreach.net,$COPTS" + printf "test $F_n $TEST... " $N + $CMD0 >/dev/null 2>"${te}0" & + pid0=$! + wait${proto}4port $PORT 1 + { echo "$da"; relsleep 10; } |$CMD1 >"${tf}1" 2>"${te}1" + rc1=$? + kill $pid0 2>/dev/null; wait + if echo "$da" |diff - "${tf}1" >$tdiff; then + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok + elif [ "$rc1" -ne 0 ] && grep "Address family not supported by protocol" "${te}1" >/dev/null; then + $PRINTF "$FAILED (EAFNOSUPPORT)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + failed + elif [ "$rc1" -ne 0 ]; then + $PRINTF "$CANT (unexpected error)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + cant + elif ! echo "$da" |diff - "${tf}1" >$tdiff; then + $PRINTF "$FAILED (diff)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + failed + else + $PRINTF "$CANT (unexpected problem)\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + cant + fi +fi # NUMCOND + ;; +esac +N=$((N+1)) + +done <<<" +TCP tcp CONNECT PORT - TCP-L - PIPE +SCTP sctp CONNECT PORT - SCTP-L - PIPE +DCCP dccp CONNECT PORT - DCCP-L - PIPE +OPENSSL tcp CONNECT PORT cafile=testsrv.pem,verify=0 SSL-L cert=testsrv.pem,key=testsrv.key,verify=0 PIPE +SOCKS4 tcp - 32.98.76.54:32109 socksport=\$PORT,socksuser=nobody TCP-L - EXEC:./socks4echo.sh +SOCKS5 tcp CONNECT \$PORT:127.0.0.1:80 - TCP-L - EXEC:./socks5server-echo.sh +PROXY tcp CONNECT 127.0.0.1:80 proxyport=\$PORT,crlf TCP-L crlf EXEC:./proxyecho.sh +" + + +# Test if TCP-CONNECT with host name resolving to IPv6 first and IPv4 second +# (due to option -6) chooses IPv4 when bind option is specific. +# This works only since version 1.8.0.3 +NAME=TCP_BIND_4 +case "$TESTS" in +*%$N%*|*%functions%*|*%internet%*|*%tcp4%*|*%tcp6%*|*%ip4%*|*%ip6%*|*%listen%*|*%socket%*|*%$NAME%*) +TEST="$NAME: TCP-CONNECT chooses IPv4 from bind" +# Start a TCP4 listener with echo function +# Start Socat TCP-CONNECT with host name resolving to IPv6 first and IPv4 +# second, and bind to IPv4 explicitly. +# When connection and data transfer work the test succeeded. +if ! eval $NUMCOND; then : +elif ! cond=$(checkconds \ + "" \ + "" \ + "" \ + "IP4 IP6 TCP LISTEN STDIO PIPE" \ + "TCP-CONNECT TCP4-LISTEN STDIO PIPE" \ + "" \ + "tcp4 tcp6" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant +elif ! SOCAT_MAIN_WAIT= $SOCAT -h |grep -e '[[:space:]]-6[[:space:]]' >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}no option -0${NORMAL}\n" $N + cant +elif [ -z "$INTERNET" -a "$RES" != 'DEVTESTS' ]; then + $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N + cant +elif [ -z "$HAVEDNS" ] && ! testfeats DEVTESTS >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}Broken DNS${NORMAL}\n" $N + cant +else + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM" + newport tcp4 + CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT PIPE" + CMD1="$TRACE $SOCAT $opts -6 - TCP-CONNECT:localhost-4-6.dest-unreach.net:$PORT,bind=127.0.0.1" + printf "test $F_n $TEST... " $N + $CMD0 >/dev/null 2>"${te}0" & + pid0=$! + waittcp4port $PORT 1 + echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" + rc1=$? + kill $pid0 2>/dev/null; wait + if echo "$da" |diff - "${tf}1" >$tdiff; then + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok + elif [ "$rc1" -ne 0 ] && grep "Address family for hostname not supported" "${te}1" >/dev/null; then + $PRINTF "$FAILED (EAFNOSUPPORT)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + failed + elif [ "$rc1" -ne 0 ]; then + $PRINTF "$CANT (unexpected error)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + cant + elif ! echo "$da" |diff - "${tf}1" >$tdiff; then + $PRINTF "$FAILED (diff)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + failed + else + $PRINTF "$CANT (unexpected problem)\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + cant + fi +fi # NUMCOND + ;; +esac +N=$((N+1)) + +# Test if TCP-CONNECT with host name resolving to IPv4 first and IPv6 second +# (due to option -4) chooses IPv6 when bind option is specific. +# This works only since version 1.8.0.3 +NAME=TCP_BIND_6 +case "$TESTS" in +*%$N%*|*%functions%*|*%internet%*|*%tcp4%*|*%tcp6%*|*%ip4%*|*%ip6%*|*%listen%*|*%socket%*|*%$NAME%*) +TEST="$NAME: TCP-CONNECT chooses IPv6 from bind" +# Start a TCP6 listener with echo function +# Start Socat TCP-CONNECT with host name resolving to IPv4 first and IPv6 +# second, and bind to IPv6 explicitly. +# When connection and data transfer work the test succeeded. +if ! eval $NUMCOND; then : +elif ! cond=$(checkconds \ + "" \ + "" \ + "" \ + "IP4 IP6 TCP LISTEN STDIO PIPE" \ + "TCP-CONNECT TCP4-LISTEN STDIO PIPE" \ + "" \ + "tcp4 tcp6" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant +elif ! SOCAT_MAIN_WAIT= $SOCAT -h |grep -e '[[:space:]]-4[[:space:]]' >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}no option -0${NORMAL}\n" $N + cant +elif [ -z "$INTERNET" -a "$RES" != 'DEVTESTS' ]; then + $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N + cant +elif [ -z "$HAVEDNS" ] && ! testfeats DEVTESTS >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}Broken DNS${NORMAL}\n" $N + cant +else + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM" + newport tcp4 + CMD0="$TRACE $SOCAT $opts TCP6-LISTEN:$PORT PIPE" + CMD1="$TRACE $SOCAT $opt -4 - TCP-CONNECT:localhost-4-6.dest-unreach.net:$PORT,bind=[::1]" + printf "test $F_n $TEST... " $N + $CMD0 >/dev/null 2>"${te}0" & + pid0=$! + waittcp4port $PORT 1 + echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" + rc1=$? + kill $pid0 2>/dev/null; wait + if echo "$da" |diff - "${tf}1" >$tdiff; then + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok + elif [ "$rc1" -ne 0 ] && grep "Address family for hostname not supported" "${te}1" >/dev/null; then + $PRINTF "$FAILED (EAFNOSUPPORT)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + failed + elif [ "$rc1" -ne 0 ]; then + $PRINTF "$CANT (unexpected error)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + cant + elif ! echo "$da" |diff - "${tf}1" >$tdiff; then + $PRINTF "$FAILED (diff)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + failed + else + $PRINTF "$CANT (unexpected problem)\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + cant + fi +fi # NUMCOND + ;; +esac +N=$((N+1)) + + +while read ADDR proto CSUFF CPARMS COPTS SADDR SOPTS PIPE; do +if [ -z "$ADDR" ] || [[ "$ADDR" == \#* ]]; then continue; fi + +if [ "X$CSUFF" != "X-" ]; then + CADDR=$ADDR-$CSUFF +else + CADDR=$ADDR +fi +CNAME=$(echo $CADDR |tr - _) +PROTO=$(toupper $proto) +FEAT=$ADDR +addr=$(tolower $ADDR) +runs=$proto +case "$CPARMS" in + PORT) newport $proto; CPARMS=$PORT ;; + *'$PORT'*) newport $proto; CPARMS=$(eval echo "$CPARMS") ;; +esac +#echo "PORT=$PORT CPARMS=$CPARMS" >&2 +case "X$COPTS" in + X-) COPTS= ;; + *'$PORT'*) newport $proto; COPTS=$(eval echo "$COPTS") ;; +esac +case "X$SOPTS" in + X-) SOPTS= ;; +esac + +# Test the retry option with *-CONNECT addresses +NAME=${CNAME}_RETRY +case "$TESTS" in +*%$N%*|*%functions%*|*%$addr%*|*%$proto%*|*%${proto}4%*|*%ip4%*|*%listen%*|*%socket%*|*%retry%*|*%$NAME%*) +TEST="$NAME: $ADDR can retry" +# Have an IPv4 listener with delay +# Start a connector whose first attempt must fail; check if the second attempt +# succeeds. +if ! eval $NUMCOND; then : +elif ! cond=$(checkconds \ + "" \ + "" \ + "" \ + "$FEAT IP4 TCP LISTEN STDIO" \ + "$CADDR $SADDR STDIO PIPE" \ + "pf retry interval" \ + "${runs}4 ${runs}6" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant +elif ! SOCAT_MAIN_WAIT= $SOCAT -h |grep -e '[[:space:]]-6[[:space:]]' >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}no option -0${NORMAL}\n" $N + cant +else +# newport $proto +#echo "PORT=$PORT CPARMS=$CPARMS" >&2 + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM" + CMD0="relsleep 5; $TRACE $SOCAT $opts $SADDR:$PORT,$SOPTS,pf=2 $PIPE" + CMD1="$TRACE $SOCAT $opts -4 STDIO $CADDR:$LOCALHOST:$CPARMS,retry=1,interval=$(relsecs 10),$COPTS" + printf "test $F_n $TEST... " $N +#date +%Y/%m/%d" "%H:%M:%S.%N + eval "$CMD0" >/dev/null 2>"${te}0" & + pid0=$! + { echo "$da"; relsleep 15; } |$CMD1 >"${tf}1" 2>"${te}1" + rc1=$? + kill $pid0 2>/dev/null; wait + if echo "$da" |diff - "${tf}1" >$tdiff; then + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok + elif [ "$rc1" -ne 0 ] && grep "Address family not supported by protocol" "${te}1" >/dev/null; then + $PRINTF "$FAILED (EAFNOSUPPORT)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + failed + elif [ "$rc1" -ne 0 ]; then + $PRINTF "$CANT (unexpected error)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + cant + elif ! echo "$da" |diff - "${tf}1" >$tdiff; then + $PRINTF "$FAILED (diff)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + failed + else + $PRINTF "$CANT (unexpected problem)\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + cant + fi +fi # NUMCOND + ;; +esac +N=$((N+1)) + +done <<<" +TCP tcp CONNECT PORT - TCP-L - PIPE +SCTP sctp CONNECT PORT - SCTP-L - PIPE +DCCP dccp CONNECT PORT - DCCP-L - PIPE +OPENSSL tcp CONNECT PORT cafile=testsrv.pem,verify=0 SSL-L cert=testsrv.pem,key=testsrv.key,verify=0 PIPE +SOCKS4 tcp - 32.98.76.54:32109 socksport=\$PORT,socksuser=nobody TCP-L - EXEC:./socks4echo.sh +SOCKS5 tcp CONNECT \$PORT:127.0.0.1:80 - TCP-L - EXEC:./socks5server-echo.sh +PROXY tcp CONNECT 127.0.0.1:80 proxyport=\$PORT,crlf TCP-L crlf EXEC:./proxyecho.sh +" + +#------------------------------------------------------------------------------ + +while read ADDR proto CSUFF CPARMS COPTS SADDR SOPTS PIPE SLOW; do +if [ -z "$ADDR" ] || [[ "$ADDR" == \#* ]]; then continue; fi + +if [ "X$CSUFF" != "X-" ]; then + CADDR=$ADDR-$CSUFF +else + CADDR=$ADDR +fi +CNAME=$(echo $CADDR |tr - _) +PROTO=$(toupper $proto) +FEAT=$ADDR +addr=$(tolower $ADDR) +runs=$proto +case "$CPARMS" in + PORT) newport $proto; CPARMS=$PORT ;; + *'$PORT'*) newport $proto; CPARMS=$(eval echo "$CPARMS") ;; +esac +#echo "PORT=$PORT CPARMS=$CPARMS" >&2 +case "X$COPTS" in + X-) COPTS= ;; + *'$PORT'*) newport $proto; COPTS=$(eval echo "$COPTS") ;; +esac +case "X$SOPTS" in + X-) SOPTS= ;; +esac + +# Test the fork and max-children options with CONNECT addresses +NAME=${CNAME}_MAXCHILDREN +case "$TESTS" in +*%$N%*|*%functions%*|*%$addr%*|*%$proto%*|*%${proto}4%*|*%ip4%*|*%listen%*|*%socket%*|*%fork%*|*%maxchildren%*|*%$NAME%*) +TEST="$NAME: $ADDR with fork,max-children" +# Start a reader process that transfers received data to an output file; +# run a sending client that forks at most 2 parallel child processes that +# transfer data from a simple directory queue to the reader but afterwards +# hang some time to prevent more child process. +# After the first two transfers write the third record directly to the file; +# a little later the Socat mechanism puts a 4th record. +# When the 4 records in the output file have the expected order the test +# succeeded. +if ! eval $NUMCOND; then : +elif ! cond=$(checkconds \ + "" \ + "" \ + "" \ + "$FEAT IP4 TCP LISTEN STDIO PIPE" \ + "$CADDR $SADDR STDIO PIPE" \ + "pf" \ + "${runs}4" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant +else +# newport $proto +#echo "PORT=$PORT CPARMS=$CPARMS" >&2 + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + tQ="$td/test$N.q" + ext=q.y.f. # some unusual extension to prevent from deleting wrong file + da="test$N $(date) $RANDOM" + CMD0="$TRACE $SOCAT $opts -lp reader $SADDR:$PORT,$SOPTS,pf=2,reuseaddr,fork $PIPE" + CMD1="$TRACE $SOCAT $opts -4 $CADDR:$LOCALHOST:$CPARMS,fork,max-children=2,interval=$(relsecs $((2*SLOW))),$COPTS SHELL:'shopt\ -s\ nullglob;\ F=\$(ls -1 $tQ|grep .$ext\\\$|head -n 1);\ test\ \"\$F\"\ ||\ exit;\ cat\ $tQ/\$F;\ mv\ -i\ $tQ/\$F\ $tQ/.\$F;\ sleep\ $(relsecs $((5*SLOW)) )'!!-" + printf "test $F_n $TEST... " $N + # create data for the generator + mkdir -p $tQ + echo "$da 1" >$tQ/01.$ext + echo "$da 2" >$tQ/02.$ext + echo "$da 4" >$tQ/04.$ext + eval "$CMD0" 2>"${te}0" & + pid0=$! + relsleep $((1*SLOW)) + eval $CMD1 2>"${te}1" >>"${tf}0" & + pid1=$! + relsleep $((4*SLOW)) +#date +%Y/%m/%d" "%H:%M:%S.%N + echo "$da 3" >>"${tf}0" + relsleep $((4*SLOW)) + kill $(childpids -r $pid0) $pid0 $(childpids -r $pid1) $pid1 2>/dev/null + wait 2>/dev/null + if ! test -e "${tf}0" || ! test -s "${tf}0"; then + $PRINTF "$FAILED\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + failed + elif $ECHO "$da 1\n$da 2\n$da 3\n$da 4" |diff - ${tf}0 >$tdiff; then + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok + else + $PRINTF "$FAILED (diff)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + failed + fi +fi # NUMCOND + ;; +esac +N=$((N+1)) + +done <<<" +TCP tcp CONNECT PORT - TCP-L - PIPE 1 +SCTP sctp CONNECT PORT - SCTP-L - PIPE 1 +DCCP dccp CONNECT PORT - DCCP-L - PIPE 1 +OPENSSL tcp CONNECT PORT cafile=testsrv.pem,verify=0 SSL-L cert=testsrv.pem,key=testsrv.key,verify=0 PIPE 7 +SOCKS4 tcp - 32.98.76.54:32109 socksport=\$PORT,socksuser=nobody TCP-L - EXEC:./socks4echo.sh 6 +SOCKS5 tcp CONNECT \$PORT:127.0.0.1:80 - TCP-L - EXEC:./socks5server-echo.sh 5 +PROXY tcp CONNECT 127.0.0.1:80 proxyport=\$PORT,crlf TCP-L crlf EXEC:./proxyecho.sh 4 +" +# detto IP6 + + +# test combined 4_6/6_4 with retry and fork + + # end of common tests ################################################################################## #================================================================================= -# here come tests that might affect your systems integrity. Put normal tests +# Here come tests that might affect your systems integrity. Put normal tests # before this paragraph. -# tests must be explicitely selected by roottough or name (not number) +# Tests must be explicitly selected by roottough or name (not number) NAME=PTYGROUPLATE case "$TESTS" in @@ -20426,7 +20124,7 @@ case "$TESTS" in TEST="$NAME: pty with group-late works on pty" # up to socat 1.7.1.1 address pty changed the ownership of /dev/ptmx instead of # the pty with options user-late, group-late, or perm-late. -# here we check for correct behaviour. +# here we check for correct behaviour. # ATTENTION: in case of failure of this test the # group of /dev/ptmx might be changed! if ! eval $NUMCOND; then :; else @@ -20462,17 +20160,14 @@ if [ $rc1 -ne 0 ]; then echo "$CMD1" cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif echo "$da" |diff - "$tf" >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi if ! ls -l $f |diff "$td/test$N.$F.ls-l" -; then $PRINTF "${RED}this test changed properties of $f!${NORMAL}\n" @@ -20493,8 +20188,11 @@ set -- $listOK; while [ "$1" ]; do echo "$1"; shift; done >"$td/success.lst" ln -sf "$td/success.lst" . set -- $listFAIL; while [ "$1" ]; do echo "$1"; shift; done >"$td/failed.lst" ln -sf "$td/failed.lst" . -sort -n <(cat "$td/success.lst" |while read x; do echo "$x OK"; done) <(cat "$td/cannot.lst" |while read x; do echo "$x CANT"; done) <(cat "$td/failed.lst" |while read x; do echo "$x FAILED"; done) >"$td/result.txt" -ln -sf "$td/result.txt" . +#sort -n <(cat "$td/success.lst" |while read x; do echo "$x OK"; done) <(cat "$td/cannot.lst" |while read x; do echo "$x CANT"; done) <(cat "$td/failed.lst" |while read x; do echo "$x FAILED"; done) >"$td/result.txt" +#ln -sf "$td/result.txt" . + +ln -sf "$td/results.txt" . + if [ "$numCANT" -gt 0 ]; then echo "CANT: $listCANT" fi @@ -20507,8 +20205,6 @@ if [ -z "$OPT_EXPECT_FAIL" ]; then exit # with rc from above statement fi -#set -vx - if [ "$OPT_EXPECT_FAIL" ]; then diff <(set -- $(echo "$EXPECT_FAIL" |tr ',' ' '); while [ "$1" ]; do echo "$1"; shift; done) "$td/failed.lst" >"$td/failed.diff" ln -sf "$td/failed.diff" . @@ -20535,7 +20231,7 @@ rm -f testsrv.* testcli.* testsrvdsa* testsrvfips* testclifips* # end # too dangerous - run as root and having a shell problem, it might purge your -# file systems +# file systems #rm -r "$td" # sometimes subprocesses hang; we want to see this @@ -20564,9 +20260,7 @@ elif ! cond=$(checkconds \ "so-reuseaddr" \ "tcp4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -20589,9 +20283,7 @@ else cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! echo "$da" |diff - "${tf}1" >$tdiff; then $PRINTF "$FAILED (diff)\n" echo "$CMD0 &" @@ -20600,9 +20292,7 @@ else cat "${te}1" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif [ ??? ]; then # The test could not run meaningfully $PRINTF "$CANT\n" @@ -20610,17 +20300,16 @@ else if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi + result fi # NUMCOND ;; esac diff --git a/xio-ascii.c b/xio-ascii.c index 2fb61b9..9493103 100644 --- a/xio-ascii.c +++ b/xio-ascii.c @@ -11,7 +11,7 @@ #include "xio-ascii.h" -/* for each 6 bit pattern we have an ASCII character in the arry */ +/* For each 6 bit pattern we have an ASCII character in the array */ const static int base64chars[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', diff --git a/xio-exec.c b/xio-exec.c index bed513c..303d429 100644 --- a/xio-exec.c +++ b/xio-exec.c @@ -84,7 +84,8 @@ static int xioopen_exec( while (*strp == ' ') { while (*++strp == ' ') ; if ((pargc & 0x07) == 0) { - pargv = Realloc(pargv, (pargc+8)*sizeof(char *)); + /*0 pargv = Realloc(pargv, (pargc+8)*sizeof(char *)); */ + pargv = Realloc3(pargv, (pargc+8)*sizeof(char *), pargc*sizeof(char *)); if (pargv == NULL) return STAT_RETRYLATER; } pargv[pargc++] = tokp; diff --git a/xio-fd.c b/xio-fd.c index 6f50629..70b8634 100644 --- a/xio-fd.c +++ b/xio-fd.c @@ -31,7 +31,7 @@ const struct optdesc opt_o_noinherit = { "o-noinherit", "noinherit", OPT_O_NOINH const struct optdesc opt_o_noatime = { "o-noatime", "noatime", OPT_O_NOATIME, GROUP_OPEN|GROUP_FD, PH_FD, TYPE_BOOL, OFUNC_FCNTL, F_SETFL, O_NOATIME }; #endif /****** for ALL addresses - with fcntl(F_SETFD) ******/ -const struct optdesc opt_cloexec = { "cloexec", NULL, OPT_CLOEXEC, GROUP_FD, PH_LATE, TYPE_BOOL, OFUNC_FCNTL, F_SETFD, FD_CLOEXEC }; +const struct optdesc opt_cloexec = { "cloexec", NULL, OPT_O_CLOEXEC, GROUP_FD, PH_LATE, TYPE_BOOL, OFUNC_FCNTL, F_SETFD, FD_CLOEXEC }; /****** ftruncate() ******/ /* this record is good for ftruncate() or ftruncate64() if available */ #if HAVE_FTRUNCATE64 diff --git a/xio-file.c b/xio-file.c index c19be4b..cb61247 100644 --- a/xio-file.c +++ b/xio-file.c @@ -20,7 +20,7 @@ static int xioopen_open(int argc, const char *argv[], struct opt *opts, int xiof const struct optdesc opt_o_rdonly = { "o-rdonly", "rdonly", OPT_O_RDONLY, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG_PATTERN, O_RDONLY, O_ACCMODE }; const struct optdesc opt_o_wronly = { "o-wronly", "wronly", OPT_O_WRONLY, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG_PATTERN, O_WRONLY, O_ACCMODE }; const struct optdesc opt_o_rdwr = { "o-rdwr", "rdwr", OPT_O_RDWR, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG_PATTERN, O_RDWR, O_ACCMODE }; -const struct optdesc opt_o_create = { "o-create", "creat", OPT_O_CREATE, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_CREAT }; +const struct optdesc opt_o_creat = { "o-creat", "creat", OPT_O_CREAT, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_CREAT }; const struct optdesc opt_o_excl = { "o-excl", "excl", OPT_O_EXCL, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_EXCL }; const struct optdesc opt_o_noctty = { "o-noctty", "noctty", OPT_O_NOCTTY, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_NOCTTY }; #ifdef O_SYNC diff --git a/xio-file.h b/xio-file.h index f592d68..be01378 100644 --- a/xio-file.h +++ b/xio-file.h @@ -8,7 +8,7 @@ extern const struct optdesc opt_o_rdonly; extern const struct optdesc opt_o_wronly; extern const struct optdesc opt_o_rdwr; -extern const struct optdesc opt_o_create; +extern const struct optdesc opt_o_creat; extern const struct optdesc opt_o_excl; extern const struct optdesc opt_o_noctty; extern const struct optdesc opt_o_sync; diff --git a/xio-fs.c b/xio-fs.c index 1678828..5630f23 100644 --- a/xio-fs.c +++ b/xio-fs.c @@ -87,7 +87,7 @@ const struct optdesc opt_fs_noatime = { "fs-noatime", "noatime", #endif /* FS_NOATIME_FL */ /* FS_DIRTY_FL ??? */ -/* FS_COMPRBLK_FL one ore more compress clusters */ +/* FS_COMPRBLK_FL one or more compress clusters */ /* FS_NOCOMPR_FL access raw compressed data */ /* FS_ECOMPR_FL compression error */ /* FS_BTREE_FL btree format dir */ diff --git a/xio-interface.c b/xio-interface.c index d870f87..c09aec5 100644 --- a/xio-interface.c +++ b/xio-interface.c @@ -71,7 +71,7 @@ int _xioopen_interface(const char *ifname, if (ifindex(ifname, &ifidx, -1) < 0) { Error1("unknown interface \"%s\"", ifname); - ifidx = 0; /* desparate attempt to continue */ + ifidx = 0; /* desperate attempt to continue */ } if (sfd->howtoend == END_UNSPEC) @@ -276,7 +276,7 @@ int _xiointerface_apply_iff( #if HAVE_STRUCT_CMSGHDR && HAVE_STRUCT_TPACKET_AUXDATA -/* Converts the ancillary message in *cmsg into a form useable for further +/* Converts the ancillary message in *cmsg into a form usable for further processing. Knows the specifics of common message types. On PACKET_AUXDATA it stored the ancillary data in the XFD. For other types: diff --git a/xio-ip.c b/xio-ip.c index 6821571..2b7deaf 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -68,7 +68,7 @@ const struct optdesc opt_ip_multicast_if ={"ip-multicast-if", "multicast-if", #ifdef IP_PKTOPTIONS const struct optdesc opt_ip_pktoptions = { "ip-pktoptions", "pktopts", OPT_IP_PKTOPTIONS, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_PKTOPTIONS }; #endif -#ifdef IP_ADD_MEMBERSHIP +#if defined(HAVE_STRUCT_IP_MREQ) || defined(HAVE_STRUCT_IP_MREQN) const struct optdesc opt_ip_add_membership = { "ip-add-membership", "membership",OPT_IP_ADD_MEMBERSHIP, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_IP_MREQN, OFUNC_SPEC, SOL_IP, IP_ADD_MEMBERSHIP }; #endif #if defined(HAVE_STRUCT_IP_MREQ_SOURCE) && defined(IP_ADD_SOURCE_MEMBERSHIP) @@ -161,6 +161,79 @@ int Res_init(void) { #endif /* HAVE_RESOLV_H */ +/* Looks for a bind option and, if found, passes it to resolver; + for IP (v4, v6) and raw (PF_UNSPEC); + returns list of addrinfo results; + returns STAT_OK if option exists and could be resolved, + STAT_NORETRY if option exists but had error, + or STAT_NOACTION if it does not exist */ +int retropt_bind_ip( + struct opt *opts, + int af, + int socktype, + int ipproto, + struct addrinfo ***bindlist, + int feats, /* TCP etc: 1..address allowed, + 3..address and port allowed + */ + const int ai_flags[2]) +{ + const char portsep[] = ":"; + const char *ends[] = { portsep, NULL }; + const char *nests[] = { "[", "]", NULL }; + bool portallowed; + char *bindname, *bindp; + char hostname[512], *hostp = hostname, *portp = NULL; + size_t hostlen = sizeof(hostname)-1; + int parsres; + int ai_flags2[2]; + int result; + + if (retropt_string(opts, OPT_BIND, &bindname) < 0) { + return STAT_NOACTION; + } + bindp = bindname; + + portallowed = (feats>=2); + parsres = + nestlex((const char **)&bindp, &hostp, &hostlen, ends, NULL, NULL, nests, + true, false, false); + if (parsres < 0) { + Error1("option too long: \"%s\"", bindp); + return STAT_NORETRY; + } else if (parsres > 0) { + Error1("syntax error in \"%s\"", bindp); + return STAT_NORETRY; + } + *hostp++ = '\0'; + if (!strncmp(bindp, portsep, strlen(portsep))) { + if (!portallowed) { + Error("port specification not allowed in this bind option"); + return STAT_NORETRY; + } else { + portp = bindp + strlen(portsep); + } + } + + /* Set AI_PASSIVE, except when it is explicitely disabled */ + ai_flags2[0] = ai_flags[0]; + ai_flags2[1] = ai_flags[1]; + if (!(ai_flags2[1] & AI_PASSIVE)) + ai_flags2[0] |= AI_PASSIVE; + + if ((result = + xiogetaddrinfo(hostname[0]!='\0'?hostname:NULL, portp, + af, socktype, ipproto, + bindlist, ai_flags2)) + != STAT_OK) { + Error2("error resolving bind option \"%s\" with af=%d", bindname, af); + return STAT_NORETRY; + } + + return STAT_OK; +} + + #if WITH_DEVTESTS /* Have a couple of hard coded sockaddr records, to be copied and adapted when @@ -386,6 +459,7 @@ int _xiogetaddrinfo(const char *node, const char *service, #else /* HAVE_PROTOTYPE_LIB_getipnodebyname || nothing */ struct hostent *host; #endif + bool restore_proto = false; int error_num; Debug8("_xiogetaddrinfo(node=\"%s\", service=\"%s\", family=%d, socktype=%d, protoco=%d, ai_flags={0x%04x/0x%04x} }, res=%p", @@ -512,15 +586,16 @@ int _xiogetaddrinfo(const char *node, const char *service, return EAI_SERVICE; } /* Probably unsupported protocol (e.g. UDP-Lite), fallback to 0 */ + restore_proto = true; hints.ai_protocol = 0; continue; } if ((error_num = Getaddrinfo(node, service, &hints, res)) != 0) { - Warn7("getaddrinfo(\"%s\", \"%s\", {0x%02x,%d,%d,%d}, {}): %d", + Warn7("getaddrinfo(\"%s\", \"%s\", {0x%02x,%d,%d,%d}, {}): %s", node?node:"NULL", service?service:"NULL", hints.ai_flags, hints.ai_family, hints.ai_socktype, hints.ai_protocol, - error_num); + gai_strerror(error_num)); if (numnode) free(numnode); @@ -540,6 +615,14 @@ int _xiogetaddrinfo(const char *node, const char *service, #endif /* WITH_MSGLEVEL <= E_DEBUG */ } + if (restore_proto) { + struct addrinfo *record = *res; + while (record) { + record->ai_protocol = protocol; + record = record->ai_next; + } + } + #elif HAVE_PROTOTYPE_LIB_getipnodebyname /* !HAVE_GETADDRINFO */ if (node != NULL) { @@ -592,7 +675,7 @@ int _xiogetaddrinfo(const char *node, const char *service, freehostent(host); } -#elsif 0 /* !HAVE_PROTOTYPE_LIB_getipnodebyname */ +#elif 0 /* !HAVE_PROTOTYPE_LIB_getipnodebyname */ if (node != NULL) { /* this is not a typical IP6 resolver function - but Linux @@ -760,6 +843,9 @@ void xiofreeaddrinfo(struct addrinfo **ai_sorted) { int ain; struct addrinfo *res; + if (ai_sorted == NULL) + return; + /* Find the original *res from getaddrinfo past NULL */ ain = 0; while (ai_sorted[ain] != NULL) @@ -843,7 +929,7 @@ int xioresolve(const char *node, const char *service, } #if defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) -/* Converts the ancillary message in *cmsg into a form useable for further +/* Converts the ancillary message in *cmsg into a form usable for further processing. knows the specifics of common message types. These are valid for IPv4 and IPv6 Returns the number of resulting syntax elements in *num @@ -902,16 +988,20 @@ int xiolog_ancillary_ip( '\0', inet4addr_info(ntohl(pktinfo->ipi_addr.s_addr), scratch3, sizeof(scratch3))); +#if HAVE_PKTINFO_IPI_SPEC_DST Notice3("Ancillary message: interface \"%s\", locaddr=%s, dstaddr=%s", xiogetifname(pktinfo->ipi_ifindex, scratch1, -1), -#if HAVE_PKTINFO_IPI_SPEC_DST inet4addr_info(ntohl(pktinfo->ipi_spec_dst.s_addr), scratch2, sizeof(scratch2)), -#else - "", -#endif inet4addr_info(ntohl(pktinfo->ipi_addr.s_addr), scratch3, sizeof(scratch3))); +#else + Notice3("Ancillary message: interface \"%s\", locaddr=%s, dstaddr=%s", + xiogetifname(pktinfo->ipi_ifindex, scratch1, -1), + "", + inet4addr_info(ntohl(pktinfo->ipi_addr.s_addr), + scratch3, sizeof(scratch3))); +#endif } return STAT_OK; #endif /* defined(IP_PKTINFO) && HAVE_STRUCT_IN_PKTINFO */ @@ -1001,7 +1091,7 @@ int xiolog_ancillary_ip( cmsgtype = "IP_OPTIONS"; cmsgname = "options"; cmsgctr = -1; /*!!!*/ break; -#if XIO_ANCILLARY_TYPE_SOLARIS +#if defined(IP_RECVTOS) && XIO_ANCILLARY_TYPE_SOLARIS case IP_RECVTOS: #else case IP_TOS: @@ -1112,13 +1202,14 @@ int xiotype_ip_add_membership( opt->value2.u_string/*param2*/, opt->value3.u_string/*ifindex*/); } else { - /*0 opt->value3.u_string = NULL; / * is NULL from init */ + opt->value3.u_string = NULL; /* is not NULL from init! */ Info3("setting option \"%s\" to {\"%s\",\"%s\"}", ent->desc->defname, opt->value.u_string/*multiaddr*/, opt->value2.u_string/*param2*/); } #else /* !HAVE_STRUCT_IP_MREQN */ + opt->value3.u_string = NULL; Info3("setting option \"%s\" to {\"%s\",\"%s\"}", ent->desc->defname, opt->value.u_string/*multiaddr*/, @@ -1128,6 +1219,9 @@ int xiotype_ip_add_membership( } #endif /* defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) */ + +#if _WITH_IP4 + #if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) int xioapply_ip_add_membership( struct single *sfd, @@ -1352,7 +1446,7 @@ int xioapply_ip_add_source_membership(struct single *sfd, struct opt *opt) { } ip4_mreq_src.imr_multiaddr = sockaddr1.ip4.sin_addr; /* second parameter is interface address */ - rc = xioresolve(opt->value.u_string/*ifaddr*/, NULL, + rc = xioresolve(opt->value2.u_string/*ifaddr*/, NULL, sfd->para.socket.la.soa.sa_family, SOCK_DGRAM, IPPROTO_IP, &sockaddr2, &socklen2, sfd->para.socket.ip.ai_flags); @@ -1361,7 +1455,7 @@ int xioapply_ip_add_source_membership(struct single *sfd, struct opt *opt) { } ip4_mreq_src.imr_interface = sockaddr2.ip4.sin_addr; /* third parameter is source address */ - rc = xioresolve(opt->value.u_string/*srcaddr*/, NULL, + rc = xioresolve(opt->value3.u_string/*srcaddr*/, NULL, sfd->para.socket.la.soa.sa_family, SOCK_DGRAM, IPPROTO_IP, &sockaddr3, &socklen3, sfd->para.socket.ip.ai_flags); @@ -1386,6 +1480,8 @@ int xioapply_ip_add_source_membership(struct single *sfd, struct opt *opt) { #endif /* HAVE_STRUCT_IP_MREQ_SOURCE */ +#endif /* _WITH_IP4 */ + #if WITH_RESOLVE #if HAVE_RESOLV_H diff --git a/xio-ip.h b/xio-ip.h index ec94e16..c6c0355 100644 --- a/xio-ip.h +++ b/xio-ip.h @@ -49,6 +49,7 @@ extern const struct optdesc opt_res_nsaddr; extern int xioinit_ip(int *pf, char ipv); +extern int retropt_bind_ip(struct opt *opts, int af, int socktype, int ipproto, struct addrinfo ***bindlist, int feats, const int ai_flags[2]); extern int xiogetaddrinfo(const char *node, const char *service, int family, int socktype, int protocol, struct addrinfo ***ai_sorted, const int ai_flags[2]); extern void xiofreeaddrinfo(struct addrinfo **ai_sorted); extern int _xio_sort_ip_addresses(struct addrinfo *themlist, struct addrinfo **ai_sorted); diff --git a/xio-ip6.c b/xio-ip6.c index 04eff08..221f01f 100644 --- a/xio-ip6.c +++ b/xio-ip6.c @@ -23,7 +23,7 @@ static char *inet6addr_info(const struct in6_addr *sa, char *buff, size_t blen); #ifdef IPV6_V6ONLY const struct optdesc opt_ipv6_v6only = { "ipv6-v6only", "ipv6only", OPT_IPV6_V6ONLY, GROUP_SOCK_IP6, PH_PREBIND, TYPE_INT, OFUNC_SOCKOPT, SOL_IPV6, IPV6_V6ONLY }; #endif -#ifdef IPV6_JOIN_GROUP +#if defined(HAVE_STRUCT_IP_MREQ) || defined(HAVE_STRUCT_IP_MREQN) const struct optdesc opt_ipv6_join_group = { "ipv6-join-group", "join-group", OPT_IPV6_JOIN_GROUP, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_IP_MREQN, OFUNC_SPEC, SOL_IPV6, IPV6_JOIN_GROUP }; #endif #ifdef MCAST_JOIN_SOURCE_GROUP @@ -249,7 +249,7 @@ int xiocheckrange_ip6(struct sockaddr_in6 *pa, struct xiorange *range) { #if defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) /* provides info about the ancillary message: - converts the ancillary message in *cmsg into a form useable for further + converts the ancillary message in *cmsg into a form usable for further processing. knows the specifics of common message types. returns the number of resulting syntax elements in *num returns a sequence of \0 terminated type strings in *typbuff diff --git a/xio-ipapp.c b/xio-ipapp.c index 1cb1b64..eab2078 100644 --- a/xio-ipapp.c +++ b/xio-ipapp.c @@ -6,7 +6,7 @@ #include "xiosysincludes.h" -#if WITH_TCP || WITH_UDP +#if WITH_TCP || WITH_UDP || WITH_SCTP || WITH_DCCP || WITH_UDPLITE #include "xioopen.h" #include "xio-socket.h" @@ -19,7 +19,8 @@ const struct optdesc opt_sourceport = { "sourceport", "sp", OPT_SOURCEPORT /*const struct optdesc opt_port = { "port", NULL, OPT_PORT, GROUP_IPAPP, PH_BIND, TYPE_USHORT, OFUNC_SPEC };*/ const struct optdesc opt_lowport = { "lowport", NULL, OPT_LOWPORT, GROUP_IPAPP, PH_LATE, TYPE_BOOL, OFUNC_SPEC }; -#if WITH_IP4 + +#if _WITH_IP4 || _WITH_IP6 /* we expect the form "host:port" */ int xioopen_ipapp_connect( int argc, @@ -31,20 +32,18 @@ int xioopen_ipapp_connect( { struct single *sfd = &xxfd->stream; struct opt *opts0 = NULL; + const char *hostname = argv[1], *portname = argv[2]; + int pf = addrdesc->arg3; int socktype = addrdesc->arg1; int ipproto = addrdesc->arg2; - int pf = addrdesc->arg3; - const char *hostname = argv[1], *portname = argv[2]; bool dofork = false; int maxchildren = 0; - union sockaddr_union us_sa, *us = &us_sa; - socklen_t uslen = sizeof(us_sa); - struct addrinfo **themarr, *themp; - char infobuff[256]; + struct addrinfo **bindarr = NULL; + struct addrinfo **themarr = NULL; + uint16_t bindport = 0; bool needbind = false; bool lowport = false; - int level; - int i; + int level = E_ERROR; int result; if (argc != 3) { @@ -52,97 +51,84 @@ int xioopen_ipapp_connect( return STAT_NORETRY; } - if (sfd->howtoend == END_UNSPEC) - sfd->howtoend = END_SHUTDOWN; + /* Apply and retrieve some options */ + result = _xioopen_ipapp_init(sfd, xioflags, opts, + &dofork, &maxchildren, + &pf, &socktype, &ipproto); + if (result != STAT_OK) + return result; - if (applyopts_single(sfd, opts, PH_INIT) < 0) - return -1; - applyopts(sfd, -1, opts, PH_INIT); + opts0 = opts; /* save remaining options for each loop */ + opts = NULL; - retropt_bool(opts, OPT_FORK, &dofork); - if (dofork) { - if (!(xioflags & XIO_MAYFORK)) { - Error("option fork not allowed here"); - return STAT_NORETRY; - } - sfd->flags |= XIO_DOESFORK; - } + Notice2("opening connection to %s:%s", hostname, portname); - retropt_int(opts, OPT_MAX_CHILDREN, &maxchildren); - - if (! dofork && maxchildren) { - Error("option max-children not allowed without option fork"); - return STAT_NORETRY; - } - - if (_xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto, - sfd->para.socket.ip.ai_flags, - &themarr, us, &uslen, &needbind, &lowport, - socktype) != STAT_OK) { - return STAT_NORETRY; - } - - if (dofork) { - xiosetchilddied(); /* set SIGCHLD handler */ - } - - if (xioparms.logopt == 'm') { - Info("starting connect loop, switching to syslog"); - diag_set('y', xioparms.syslogfac); xioparms.logopt = 'y'; - } else { - Info("starting connect loop"); - } - - do { /* loop over retries, and forks */ - - /* Loop over themarr (which had been "ai_sorted") */ - result = STAT_RETRYLATER; - i = 0; - themp = themarr[i++]; - while (themp != NULL) { - Notice1("opening connection to %s", - sockaddr_info(themp->ai_addr, themp->ai_addrlen, - infobuff, sizeof(infobuff))); + do { /* loop over retries and/or forks */ + int _errno; #if WITH_RETRY - if (sfd->forever || sfd->retry) { - level = E_INFO; - } else if (themarr[i] != NULL) { - level = E_WARN; - } else + if (sfd->forever || sfd->retry) { + level = E_NOTICE; + } else #endif /* WITH_RETRY */ - level = E_ERROR; + level = E_WARN; - result = - _xioopen_connect(sfd, - needbind?us:NULL, uslen, - themp->ai_addr, themp->ai_addrlen, - opts, pf?pf:themp->ai_family, socktype, ipproto, - lowport, level); - if (result == STAT_OK) - break; - themp = themarr[i++]; - if (themp == NULL) { - result = STAT_RETRYLATER; - } - } + opts = copyopts(opts0, GROUP_ALL); + + result = + _xioopen_ipapp_prepare(&opts, opts0, hostname, portname, + pf, socktype, ipproto, + sfd->para.socket.ip.ai_flags, + &themarr, &bindarr, &bindport, &needbind, &lowport); switch (result) { case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (sfd->forever || sfd->retry) { - --sfd->retry; - if (result == STAT_RETRYLATER) { + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL); - } - dropopts(opts, PH_ALL); free(opts); opts = copyopts(opts0, GROUP_ALL); + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + freeopts(opts); continue; } #endif /* WITH_RETRY */ - default: + /* FALLTHROUGH */ + case STAT_NORETRY: + if (bindarr != NULL) xiofreeaddrinfo(bindarr); xiofreeaddrinfo(themarr); - free(opts0);free(opts); + freeopts(opts); + freeopts(opts0); + return result; + } + + result = + _xioopen_ipapp_connect(sfd, hostname, opts, themarr, + needbind, bindarr, bindport, lowport, level); + _errno = errno; + if (bindarr != NULL) + xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + switch (result) { + case STAT_OK: break; +#if WITH_RETRY + case STAT_RETRYLATER: + case STAT_RETRYNOW: + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) { + Nanosleep(&sfd->intervall, NULL); + } + freeopts(opts); + continue; + } +#endif /* WITH_RETRY */ + /* FALLTHROUGH */ + default: + Error4("%s:%s:%s: %s", argv[0], argv[1], argv[2], + _errno?strerror(_errno):"(See above)"); + freeopts(opts); + freeopts(opts0); return result; } @@ -155,16 +141,18 @@ int xioopen_ipapp_connect( so Notice is too weak */ } while ((pid = xio_fork(false, level, sfd->shutup)) < 0) { - if (sfd->forever || --sfd->retry) { - Nanosleep(&sfd->intervall, NULL); continue; + if (sfd->forever || sfd->retry--) { + Nanosleep(&sfd->intervall, NULL); + continue; } - xiofreeaddrinfo(themarr); - free(opts0); + freeopts(opts); + freeopts(opts0); return STAT_RETRYLATER; } if (pid == 0) { /* child process */ - sfd->forever = false; sfd->retry = 0; + sfd->forever = false; + sfd->retry = 0; break; } @@ -176,107 +164,269 @@ int xioopen_ipapp_connect( Info1("all %d allowed children are active, waiting", maxchildren); Nanosleep(&sfd->intervall, NULL); } - dropopts(opts, PH_ALL); free(opts); opts = copyopts(opts0, GROUP_ALL); + freeopts(opts); continue; /* with next socket() bind() connect() */ } else #endif /* WITH_RETRY */ { break; } - } while (true); + } while (true); /* end of loop over retries and/or forks */ /* only "active" process breaks (master without fork, or child) */ - xiofreeaddrinfo(themarr); - if ((result = _xio_openlate(sfd, opts)) < 0) { - free(opts0);free(opts); - return result; - } - free(opts0); free(opts); - return 0; + Notice2("successfully connected to %s:%s", hostname, portname); + + result = _xio_openlate(sfd, opts); + freeopts(opts); + freeopts(opts0); + return result; } -/* returns STAT_OK on success or some other value on failure +/* This function performs static initializations for addresses like TCP-CONNECT + before start of the outer loop: + it retrieves some options + returns STAT_OK on success or some other value on failure; + applies and consumes the following options: + PH_INIT, OPT_FORK, OPT_MAX_CHILDREN, OPT_PROTOCOL_FAMILY, OPT_SO_TYPE, + OPT_SO_PROTOTYPE +*/ +int _xioopen_ipapp_init( + struct single *sfd, + int xioflags, + struct opt *opts, + bool *dofork, + int *maxchildren, + int *pf, + int *socktype, + int *ipproto) +{ + if (sfd->howtoend == END_UNSPEC) + sfd->howtoend = END_SHUTDOWN; + + if (applyopts_single(sfd, opts, PH_INIT) < 0) + return -1; + if (applyopts(sfd, -1, opts, PH_INIT) < 0) + return -1; + + retropt_bool(opts, OPT_FORK, dofork); + if (dofork) { + if (!(xioflags & XIO_MAYFORK)) { + Error1("%s: option fork not allowed here", sfd->addr->defname); + return STAT_NORETRY; + } + sfd->flags |= XIO_DOESFORK; + } + + retropt_int(opts, OPT_MAX_CHILDREN, maxchildren); + if (! dofork && maxchildren) { + Error1("%s: option max-children not allowed without option fork", sfd->addr->defname); + return STAT_NORETRY; + } + + retropt_socket_pf(opts, pf); + retropt_int(opts, OPT_SO_TYPE, socktype); + retropt_int(opts, OPT_SO_PROTOTYPE, ipproto); + + if (dofork) { + xiosetchilddied(); /* set SIGCHLD handler */ + } + + if (xioparms.logopt == 'm') { + Info("starting connect loop, switching to syslog"); + diag_set('y', xioparms.syslogfac); + xioparms.logopt = 'y'; + } else { + Info("starting connect loop"); + } + + return STAT_OK; +} + + +/* This function performs preparations for addresses like TCP-CONNECT + at the beginning of the outer (retry/fork) loop: + it evaluates some options and performs name resolution of both server + (target, "them") address and bind ("us") address. + It is intended to be invoked before the connect loop starts; + returns STAT_OK on success or some other value on failure; applies and consumes the following options: PH_EARLY - OPT_PROTOCOL_FAMILY, OPT_BIND, OPT_SOURCEPORT, OPT_LOWPORT - */ -int - _xioopen_ipapp_prepare( - struct opt *opts, - struct opt **opts0, - const char *hostname, - const char *portname, - int *pf, - int protocol, - const int ai_flags[2], - struct addrinfo ***themarr, - union sockaddr_union *us, - socklen_t *uslen, - bool *needbind, - bool *lowport, - int socktype) { + OPT_BIND, OPT_SOURCEPORT, OPT_LOWPORT + returns STAT_OK, STAT_RETRYLATER, or STAT_NORETRY (+errno) +*/ +int _xioopen_ipapp_prepare( + struct opt **opts, + struct opt *opts0, + const char *hostname, + const char *portname, + int pf, + int socktype, + int protocol, + const int ai_flags[2], + struct addrinfo ***themarr, /* always from getaddrinfo(); xiofreeaddrinfo()! */ + struct addrinfo ***bindarr, /* on bind from getaddrinfo(); xiofreeaddrinfo()! */ + uint16_t *bindport, /* for bind without address */ + bool *needbind, + bool *lowport) +{ uint16_t port; int rc; - retropt_socket_pf(opts, pf); + *opts = copyopts(opts0, GROUP_ALL); if (hostname != NULL || portname != NULL) { - rc = xiogetaddrinfo(hostname, portname, *pf, socktype, protocol, + rc = xiogetaddrinfo(hostname, portname, pf, socktype, protocol, themarr, ai_flags); if (rc == EAI_AGAIN) { Warn4("_xioopen_ipapp_prepare(node=\"%s\", service=\"%s\", pf=%d, ...): %s", hostname?hostname:"NULL", portname?portname:"NULL", - *pf, gai_strerror(rc)); + pf, gai_strerror(rc)); + errno = EAGAIN; return STAT_RETRYLATER; } else if (rc != 0) { Error4("_xioopen_ipapp_prepare(node=\"%s\", service=\"%s\", pf=%d, ...): %s", hostname?hostname:"NULL", portname?portname:"NULL", - *pf, (rc == EAI_SYSTEM)?strerror(errno):gai_strerror(rc)); + pf, (rc == EAI_SYSTEM)?strerror(errno):gai_strerror(rc)); + errno = 0; /* unspecified */ return STAT_NORETRY; /*! STAT_RETRYLATER? */ } } - applyopts(NULL, -1, opts, PH_EARLY); + applyopts(NULL, -1, *opts, PH_EARLY); /* 3 means: IP address AND port accepted */ - if (retropt_bind(opts, (*pf!=PF_UNSPEC)?*pf:(**themarr)->ai_family, - socktype, protocol, (struct sockaddr *)us, uslen, 3, - ai_flags) + if (retropt_bind_ip(*opts, pf, socktype, protocol, bindarr, 3, ai_flags) != STAT_NOACTION) { *needbind = true; - } else { - switch ((*pf!=PF_UNSPEC)?*pf:(**themarr)->ai_family) { -#if WITH_IP4 - case PF_INET: socket_in_init(&us->ip4); *uslen = sizeof(us->ip4); break; -#endif /* WITH_IP4 */ -#if WITH_IP6 - case PF_INET6: socket_in6_init(&us->ip6); *uslen = sizeof(us->ip6); break; -#endif /* WITH_IP6 */ - default: Error("unsupported protocol family"); - } } - - if (retropt_2bytes(opts, OPT_SOURCEPORT, &port) >= 0) { - switch ((*pf!=PF_UNSPEC)?*pf:(**themarr)->ai_family) { + if (retropt_2bytes(*opts, OPT_SOURCEPORT, &port) >= 0) { + if (*bindarr) { + struct addrinfo **bindp; + bindp = *bindarr; + switch ((*bindp)->ai_family) { #if WITH_IP4 - case PF_INET: us->ip4.sin_port = htons(port); break; + case PF_INET: ((struct sockaddr_in *)(*bindp)->ai_addr)->sin_port = htons(port); break; #endif /* WITH_IP4 */ #if WITH_IP6 - case PF_INET6: us->ip6.sin6_port = htons(port); break; + case PF_INET6: ((struct sockaddr_in6 *)(*bindp)->ai_addr)->sin6_port = htons(port); break; #endif /* WITH_IP6 */ - default: Error("unsupported protocol family"); + default: + Error("unsupported protocol family"); + errno = EPROTONOSUPPORT; + return STAT_NORETRY; + } + } else { + *bindport = port; } *needbind = true; } - retropt_bool(opts, OPT_LOWPORT, lowport); - - *opts0 = copyopts(opts, GROUP_ALL); + retropt_bool(*opts, OPT_LOWPORT, lowport); return STAT_OK; } -#endif /* WITH_IP4 */ + +#endif /* _WITH_IP4 || _WITH_IP6 */ + + +/* Tries to connect to the addresses in themarr, for each one it tries to bind + to the addresses in bindarr. + Ends on success or when all attempts failed. + Returns STAT_OK on success, or STAT_RETRYLATER (+errno) on failure. */ +int _xioopen_ipapp_connect(struct single *sfd, + const char *hostname, + struct opt *opts, + struct addrinfo **themarr, + bool needbind, + struct addrinfo **bindarr, + uint16_t bindport, + bool lowport, + int level) +{ + struct addrinfo **themp; + struct addrinfo **bindp; + union sockaddr_union bindaddr = {0}; + union sockaddr_union *bindaddrp = NULL; + socklen_t bindlen = 0; + char infobuff[256]; + int _errno; + int result = STAT_OK; + + --level; + + /* Loop over server addresses (themarr) */ + themp = themarr; + while (*themp != NULL) { + Notice1("opening connection to %s", + sockaddr_info((*themp)->ai_addr, (*themp)->ai_addrlen, + infobuff, sizeof(infobuff))); + + if (*(themp+1) == NULL) { + ++level; /* last attempt */ + } + + /* Loop over array (list) of bind addresses */ + if (needbind && bindarr != NULL) { + /* Bind by hostname, use resolvers results list */ + bindp = bindarr; + while (*bindp != NULL) { + if ((*bindp)->ai_family == (*themp)->ai_family) + break; + ++bindp; + } + if (*bindp == NULL) { + Warn3("%s: No bind address with matching address family (%d) of %s available", + sfd->addr->defname, (*themp)->ai_family, hostname); + ++themp; + if ((*themp) == NULL) { + result = STAT_RETRYLATER; + } + _errno = ENOPROTOOPT; + continue; + } + bindaddrp = (union sockaddr_union *)(*bindp)->ai_addr; + bindlen = (*bindp)->ai_addrlen; + } else if (needbind && bindport) { + /* Bind by sourceport option */ + switch ((*themp)->ai_family) { +#if WITH_IP4 + case PF_INET: + bindaddr.ip4.sin_family = (*themp)->ai_family; + bindaddr.ip4.sin_port = htons(bindport); + bindaddrp = &bindaddr; + bindlen = sizeof(bindaddr.ip4); + break; +#endif +#if WITH_IP6 + case PF_INET6: + bindaddr.ip6.sin6_family = (*themp)->ai_family; + bindaddr.ip6.sin6_port = htons(bindport); + bindaddrp = &bindaddr; + bindlen = sizeof(bindaddr.ip6); + break; +#endif + } + } + + result = + _xioopen_connect(sfd, + bindaddrp, bindlen, + (*themp)->ai_addr, (*themp)->ai_addrlen, + opts, /*pf?pf:*/(*themp)->ai_family, (*themp)->ai_socktype, (*themp)->ai_protocol, + lowport, level); + if (result == STAT_OK) + break; + _errno = errno; + ++themp; + if (*themp == NULL) + result = STAT_RETRYLATER; + } /* end of loop over target addresses */ + + if (result != STAT_OK) + errno = _errno; + return result; +} #if WITH_TCP && WITH_LISTEN @@ -303,7 +453,7 @@ int _xioopen_ipapp_listen_prepare( retropt_string(opts, OPT_BIND, &bindname); - /* Set AI_PASSIVE, except when it is explicitely disabled */ + /* Set AI_PASSIVE, except when it is explicitly disabled */ ai_flags2[0] = ai_flags[0]; ai_flags2[1] = ai_flags[1]; if (!(ai_flags2[1] & AI_PASSIVE)) @@ -382,6 +532,6 @@ int xioopen_ipapp_listen( return result; return 0; } -#endif /* WITH_IP4 && WITH_TCP && WITH_LISTEN */ +#endif /* WITH_TCP && WITH_LISTEN */ -#endif /* WITH_TCP || WITH_UDP */ +#endif /* WITH_TCP || WITH_UDP || WITH_SCTP || WITH_DCCP || WITH_UDPLITE */ diff --git a/xio-ipapp.h b/xio-ipapp.h index af9e7b4..e190e36 100644 --- a/xio-ipapp.h +++ b/xio-ipapp.h @@ -15,11 +15,9 @@ extern const struct optdesc opt_sourceport; extern const struct optdesc opt_lowport; extern int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc); -extern int _xioopen_ipapp_prepare(struct opt *opts, struct opt **opts0, const char *hostname, const char *portname, int *pf, int protocol, const int ai_flags[2], struct addrinfo ***themlist, union sockaddr_union *us, socklen_t *uslen, bool *needbind, bool *lowport, int socktype); -extern int _xioopen_ip4app_connect(const char *hostname, const char *portname, - struct single *xfd, - int socktype, int ipproto, void *protname, - struct opt *opts); +extern int _xioopen_ipapp_init(struct single *sfd, int xioflags, struct opt *opts, bool *dofork, int *maxchildren, int *pf, int *socktype, int *protocol); +extern int _xioopen_ipapp_prepare(struct opt **opts, struct opt *opts0, const char *hostname, const char *portname, int pf, int socktype, int protocol, const int ai_flags[2], struct addrinfo ***themarr, struct addrinfo ***bindarr, uint16_t *bindport, bool *needbind, bool *lowport); +extern int _xioopen_ipapp_connect(struct single *sfd, const char *hostname, struct opt *opts, struct addrinfo **themarr, bool needbind, struct addrinfo **bindarr, uint16_t bindport, bool lowport, int level); extern int xioopen_ipapp_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc); extern int _xioopen_ipapp_listen_prepare(struct opt *opts, struct opt **opts0, const char *portname, int *pf, int ipproto, const int ai_flags[2], union sockaddr_union *us, socklen_t *uslen, int socktype); diff --git a/xio-openssl.c b/xio-openssl.c index 1278bf4..9a2ca62 100644 --- a/xio-openssl.c +++ b/xio-openssl.c @@ -5,7 +5,7 @@ /* this file contains the implementation of the openssl addresses */ #include "xiosysincludes.h" -#if WITH_OPENSSL /* make this address configure dependend */ +#if WITH_OPENSSL /* make this address configure dependent */ #include <openssl/conf.h> #include <openssl/x509v3.h> @@ -26,7 +26,6 @@ (not only tcp, but also pipes, stdin, files...) for tcp we want to provide support for socks and proxy. read and write functions must use the openssl crypt versions. - but currently only plain tcp4 is implemented. */ /* Linux: "man 3 ssl" */ @@ -239,13 +238,13 @@ static int xioopen_openssl_connect( int socktype = SOCK_STREAM; int ipproto = IPPROTO_TCP; bool dofork = false; - union sockaddr_union us_sa, *us = &us_sa; - socklen_t uslen = sizeof(us_sa); - struct addrinfo **themarr, *themp; + int maxchildren = 0; + struct addrinfo **bindarr = NULL; + struct addrinfo **themarr = NULL; + uint16_t bindport = 0; bool needbind = false; bool lowport = false; int level = E_ERROR; - int i; SSL_CTX* ctx; bool opt_ver = true; /* verify peer certificate */ char *opt_cert = NULL; /* file name of client certificate */ @@ -255,7 +254,7 @@ static int xioopen_openssl_connect( int result; if (!(xioflags & XIO_MAYCONVERT)) { - Error("address with data processing not allowed here"); + Error1("%s: address with data processing not allowed here", argv[0]); return STAT_NORETRY; } sfd->flags |= XIO_DOESCONVERT; @@ -267,20 +266,12 @@ static int xioopen_openssl_connect( hostname = argv[1]; portname = argv[2]; if (hostname[0] == '\0') { - /* we catch this explicitely because empty commonname (peername) disables + /* We catch this explicitly because empty commonname (peername) disables commonName check of peer certificate */ Error1("%s: empty host name", argv[0]); return STAT_NORETRY; } - if (sfd->howtoend == END_UNSPEC) - sfd->howtoend = END_SHUTDOWN; - if (applyopts_single(sfd, opts, PH_INIT) < 0) - return -1; - applyopts(sfd, -1, opts, PH_INIT); - - retropt_bool(opts, OPT_FORK, &dofork); - retropt_string(opts, OPT_OPENSSL_CERTIFICATE, &opt_cert); retropt_string(opts, OPT_OPENSSL_COMMONNAME, (char **)&opt_commonname); #if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name) @@ -316,73 +307,83 @@ static int xioopen_openssl_connect( socktype = SOCK_DGRAM; ipproto = IPPROTO_UDP; } - retropt_int(opts, OPT_SO_TYPE, &socktype); - retropt_int(opts, OPT_SO_PROTOTYPE, &ipproto); - result = - _xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto, - sfd->para.socket.ip.ai_flags, - &themarr, us, &uslen, - &needbind, &lowport, socktype); - if (result != STAT_OK) return STAT_NORETRY; + /* Apply and retrieve some options */ + result = _xioopen_ipapp_init(sfd, xioflags, opts, + &dofork, &maxchildren, + &pf, &socktype, &ipproto); + if (result != STAT_OK) + return result; - if (xioparms.logopt == 'm') { - Info("starting connect loop, switching to syslog"); - diag_set('y', xioparms.syslogfac); xioparms.logopt = 'y'; - } else { - Info("starting connect loop"); - } + opts0 = opts; /* save remaining options for each loop */ + opts = NULL; - do { /* loop over failed connect and SSL handshake attempts */ + Notice2("opening OpenSSL connection to %s:%s", hostname, portname); - /* Loop over themarr (which had been "ai_sorted") */ - i = 0; - themp = themarr[i++]; - while (themp != NULL) { + do { /* loop over retries (failed connect and SSL handshake attempts) and/or forks */ + int _errno; #if WITH_RETRY - if (sfd->forever || sfd->retry || themarr[i] != NULL) { - level = E_INFO; - } else + if (sfd->forever || sfd->retry) { + level = E_NOTICE; + } else #endif /* WITH_RETRY */ - level = E_ERROR; + level = E_WARN; - /* This cannot fork because we retrieved fork option above */ - result = - _xioopen_connect(sfd, - needbind?us:NULL, uslen, - themp->ai_addr, themp->ai_addrlen, - opts, pf?pf:themp->ai_addr->sa_family, socktype, ipproto, lowport, level); - if (result == STAT_OK) - break; - themp = themarr[i++]; - if (themp == NULL) { - result = STAT_RETRYLATER; - } - } + opts = copyopts(opts0, GROUP_ALL); + + result = + _xioopen_ipapp_prepare(&opts, opts0, hostname, portname, + pf, socktype, ipproto, + sfd->para.socket.ip.ai_flags, + &themarr, &bindarr, &bindport, &needbind, &lowport); switch (result) { case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (sfd->forever || sfd->retry) { - dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) + Nanosleep(&sfd->intervall, NULL); + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + freeopts(opts); + continue; + } +#endif /* WITH_RETRY */ + case STAT_NORETRY: + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + freeopts(opts); + freeopts(opts0); + return result; + } + + Notice2("opening connection to server %s:%s", hostname, portname); + result = + _xioopen_ipapp_connect(sfd, hostname, opts, themarr, + needbind, bindarr, bindport, lowport, level); + _errno = errno; + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + switch (result) { + case STAT_OK: break; +#if WITH_RETRY + case STAT_RETRYLATER: + case STAT_RETRYNOW: + if (sfd->forever || sfd->retry--) { if (result == STAT_RETRYLATER) { Nanosleep(&sfd->intervall, NULL); } - --sfd->retry; + freeopts(opts); continue; } - xiofreeaddrinfo(themarr); - return STAT_NORETRY; #endif /* WITH_RETRY */ default: - xiofreeaddrinfo(themarr); - return result; - } - /*! isn't this too early? */ - if ((result = _xio_openlate(sfd, opts)) < 0) { - xiofreeaddrinfo(themarr); + Error4("%s:%s:%s: %s", argv[0], hostname, portname, + _errno?strerror(_errno):"(See above)"); + freeopts(opts0); + freeopts(opts); return result; } @@ -393,19 +394,19 @@ static int xioopen_openssl_connect( #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (sfd->forever || sfd->retry) { - Close(sfd->fd); - dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); + if (sfd->forever || sfd->retry--) { if (result == STAT_RETRYLATER) { Nanosleep(&sfd->intervall, NULL); } - --sfd->retry; + freeopts(opts); + Close(sfd->fd); continue; } #endif /* WITH_RETRY */ default: - xiofreeaddrinfo(themarr); - return STAT_NORETRY; + freeopts(opts); + freeopts(opts0); + return result; } if (dofork) { @@ -420,15 +421,19 @@ static int xioopen_openssl_connect( level = E_WARN; } while ((pid = xio_fork(false, level, sfd->shutup)) < 0) { - if (sfd->forever || --sfd->retry) { - Nanosleep(&sfd->intervall, NULL); continue; + if (sfd->forever || sfd->retry--) { + Nanosleep(&sfd->intervall, NULL); + freeopts(opts); + continue; } - xiofreeaddrinfo(themarr); + freeopts(opts); + freeopts(opts0); return STAT_RETRYLATER; } if (pid == 0) { /* child process */ - sfd->forever = false; sfd->retry = 0; + sfd->forever = false; + sfd->retry = 0; break; } @@ -438,21 +443,29 @@ static int xioopen_openssl_connect( sfd->para.openssl.ssl = NULL; /* with and without retry */ Nanosleep(&sfd->intervall, NULL); - dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); + while (maxchildren > 0 && num_child >= maxchildren) { + Info1("all %d allowed children are active, waiting", maxchildren); + Nanosleep(&sfd->intervall, NULL); + } + freeopts(opts); continue; /* with next socket() bind() connect() */ } #endif /* WITH_RETRY */ break; + } while (true); /* drop out on success */ - xiofreeaddrinfo(themarr); openssl_conn_loginfo(sfd->para.openssl.ssl); free((void *)opt_commonname); free((void *)opt_snihost); - /* fill in the fd structure */ - return STAT_OK; + Notice2("successfully connected to SSL server %s:%s", hostname, portname); + + result = _xio_openlate(sfd, opts); + freeopts(opts); + freeopts(opts0); + return result; } @@ -702,7 +715,7 @@ int _xioopen_openssl_listen(struct single *sfd, const char *opt_commonname, SSL_CTX *ctx, int level) { - char error_string[120]; + char error_string[256]; unsigned long err; int errint, ret; @@ -764,7 +777,7 @@ int _xioopen_openssl_listen(struct single *sfd, while (err = ERR_get_error()) { ERR_error_string_n(err, error_string, sizeof(error_string)); Msg4(level, "SSL_accept(): %s / %s / %s / %s", error_string, - ERR_lib_error_string(err), ERR_func_error_string(err), + ERR_lib_error_string(err), error_string, ERR_reason_error_string(err)); } /* Msg1(level, "SSL_accept(): %s", ERR_error_string(e, buf));*/ @@ -793,7 +806,7 @@ int _xioopen_openssl_listen(struct single *sfd, #if OPENSSL_VERSION_NUMBER >= 0x00908000L /* In OpenSSL 0.9.7 compression methods could be added using - * SSL_COMP_add_compression_method(3), but the implemntation is not compatible + * SSL_COMP_add_compression_method(3), but the implementation is not compatible * with the standard (RFC3749). */ static int openssl_setup_compression(SSL_CTX *ctx, char *method) @@ -1976,12 +1989,20 @@ static int xioSSL_set_fd(struct single *sfd, int level) { should not retry for any reason. */ static int xioSSL_connect(struct single *sfd, const char *opt_commonname, bool opt_ver, int level) { - char error_string[120]; - int errint, status, ret; + sigset_t masksigs, oldsigs; + char error_string[256]; + int errint, status, _errno, ret; unsigned long err; + sigemptyset(&masksigs); + sigaddset(&masksigs, SIGCHLD); + sigaddset(&masksigs, SIGUSR1); + Sigprocmask(SIG_BLOCK, &masksigs, &oldsigs); /* connect via SSL by performing handshake */ - if ((ret = sycSSL_connect(sfd->para.openssl.ssl)) <= 0) { + ret = sycSSL_connect(sfd->para.openssl.ssl); + _errno = errno; + Sigprocmask(SIG_SETMASK, &oldsigs, NULL); + if (ret <= 0) { /*if (ERR_peek_error() == 0) Msg(level, "SSL_connect() failed");*/ errint = SSL_get_error(sfd->para.openssl.ssl, ret); switch (errint) { @@ -2005,14 +2026,14 @@ static int xioSSL_connect(struct single *sfd, const char *opt_commonname, if (ret == 0) { Msg(level, "SSL_connect(): socket closed by peer"); } else if (ret == -1) { - Msg1(level, "SSL_connect(): %s", strerror(errno)); + Msg1(level, "SSL_connect(): %s", strerror(_errno)); } } else { Msg(level, "I/O error"); /*!*/ while (err = ERR_get_error()) { ERR_error_string_n(err, error_string, sizeof(error_string)); Msg4(level, "SSL_connect(): %s / %s / %s / %s", error_string, - ERR_lib_error_string(err), ERR_func_error_string(err), + ERR_lib_error_string(err), error_string, ERR_reason_error_string(err)); } } @@ -2037,7 +2058,7 @@ static int xioSSL_connect(struct single *sfd, const char *opt_commonname, /* on result < 0: errno is set (at least to EIO) */ ssize_t xioread_openssl(struct single *pipe, void *buff, size_t bufsiz) { unsigned long err; - char error_string[120]; + char error_string[256]; int _errno = EIO; /* if we have no better idea about nature of error */ int errint, ret; @@ -2072,7 +2093,7 @@ ssize_t xioread_openssl(struct single *pipe, void *buff, size_t bufsiz) { while (err = ERR_get_error()) { ERR_error_string_n(err, error_string, sizeof(error_string)); Error4("SSL_read(): %s / %s / %s / %s", error_string, - ERR_lib_error_string(err), ERR_func_error_string(err), + ERR_lib_error_string(err), error_string, ERR_reason_error_string(err)); } } @@ -2098,7 +2119,7 @@ ssize_t xiopending_openssl(struct single *pipe) { /* on result < 0: errno is set (at least to EIO) */ ssize_t xiowrite_openssl(struct single *pipe, const void *buff, size_t bufsiz) { unsigned long err; - char error_string[120]; + char error_string[256]; int _errno = EIO; /* if we have no better idea about nature of error */ int errint, ret; @@ -2131,7 +2152,7 @@ ssize_t xiowrite_openssl(struct single *pipe, const void *buff, size_t bufsiz) { while (err = ERR_get_error()) { ERR_error_string_n(err, error_string, sizeof(error_string)); Error4("SSL_write(): %s / %s / %s / %s", error_string, - ERR_lib_error_string(err), ERR_func_error_string(err), + ERR_lib_error_string(err), error_string, ERR_reason_error_string(err)); } } diff --git a/xio-openssl.h b/xio-openssl.h index 204aca6..3570856 100644 --- a/xio-openssl.h +++ b/xio-openssl.h @@ -5,7 +5,7 @@ #ifndef __xio_openssl_included #define __xio_openssl_included 1 -#if WITH_OPENSSL /* make this address configure dependend */ +#if WITH_OPENSSL /* make this address configure dependent */ #define SSLIO_BASE 0x53530000 /* "SSxx" */ #define SSLIO_MASK 0xffff0000 diff --git a/xio-posixmq.c b/xio-posixmq.c index 186e932..6fb969f 100644 --- a/xio-posixmq.c +++ b/xio-posixmq.c @@ -15,18 +15,21 @@ #if WITH_POSIXMQ -static int _posixmq_unlink( - const char *name, - int level); /* message level on error */ +static int _posixmq_flush(struct single *sfd); +static int _posixmq_unlink(const char *name, int level); static int xioopen_posixmq(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); -const struct addrdesc xioaddr_posixmq_bidir = { "POSIXMQ-BIDIRECTIONAL", 1+XIO_RDWR, xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY, XIO_RDWR, 0, 0 HELP(":<mqname>") }; -const struct addrdesc xioaddr_posixmq_read = { "POSIXMQ-READ", 1+XIO_RDONLY, xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY, XIO_RDONLY, 0, 0 HELP(":<mqname>") }; -const struct addrdesc xioaddr_posixmq_receive = { "POSIXMQ-RECEIVE", 1+XIO_RDONLY, xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD, XIO_RDONLY, XIOREAD_RECV_ONESHOT, 0 HELP(":<mqname>") }; -const struct addrdesc xioaddr_posixmq_send = { "POSIXMQ-SEND", 1+XIO_WRONLY, xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD, XIO_WRONLY, 0, 0 HELP(":<mqname>") }; +const struct addrdesc xioaddr_posixmq_bidir = { "POSIXMQ-BIDIRECTIONAL", 1+XIO_RDWR, xioopen_posixmq, GROUP_FD|GROUP_OPEN|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY, XIO_RDWR, 0, 0 HELP(":<mqname>") }; +const struct addrdesc xioaddr_posixmq_read = { "POSIXMQ-READ", 1+XIO_RDONLY, xioopen_posixmq, GROUP_FD|GROUP_OPEN|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY, XIO_RDONLY, 0, 0 HELP(":<mqname>") }; +const struct addrdesc xioaddr_posixmq_receive = { "POSIXMQ-RECEIVE", 1+XIO_RDONLY, xioopen_posixmq, GROUP_FD|GROUP_OPEN|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD, XIO_RDONLY, XIOREAD_RECV_ONESHOT, 0 HELP(":<mqname>") }; +const struct addrdesc xioaddr_posixmq_send = { "POSIXMQ-SEND", 1+XIO_WRONLY, xioopen_posixmq, GROUP_FD|GROUP_OPEN|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD, XIO_WRONLY, 0, 0 HELP(":<mqname>") }; +const struct addrdesc xioaddr_posixmq_write = { "POSIXMQ-WRITE", 1+XIO_WRONLY, xioopen_posixmq, GROUP_FD|GROUP_OPEN|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD, XIO_WRONLY, 0, 0 HELP(":<mqname>") }; -const struct optdesc opt_posixmq_priority = { "posixmq-priority", "mq-pri", OPT_POSIXMQ_PRIORITY, GROUP_POSIXMQ, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(para.posixmq.prio), XIO_SIZEOF(para.posixmq.prio), 0 }; +const struct optdesc opt_posixmq_priority = { "posixmq-priority", "mq-prio", OPT_POSIXMQ_PRIORITY, GROUP_POSIXMQ, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(para.posixmq.prio), XIO_SIZEOF(para.posixmq.prio), 0 }; +const struct optdesc opt_posixmq_flush = { "posixmq-flush", "mq-flush", OPT_POSIXMQ_FLUSH, GROUP_POSIXMQ, PH_EARLY, TYPE_BOOL, OFUNC_SPEC, 0, 0, 0 }; +const struct optdesc opt_posixmq_maxmsg = { "posixmq-maxmsg", "mq-maxmsg", OPT_POSIXMQ_MAXMSG, GROUP_POSIXMQ, PH_OPEN, TYPE_LONG, OFUNC_SPEC, 0, 0, 0 }; +const struct optdesc opt_posixmq_msgsize = { "posixmq-msgsize", "mq-msgsize", OPT_POSIXMQ_MSGSIZE, GROUP_POSIXMQ, PH_OPEN, TYPE_LONG, OFUNC_SPEC, 0, 0, 0 }; /* _read(): open immediately, stay in transfer loop _recv(): wait until data (how we know there is??), oneshot, opt.fork @@ -45,8 +48,18 @@ static int xioopen_posixmq( int dirs = addrdesc->arg1; int oneshot = addrdesc->arg2; bool opt_unlink_early = false; + bool nonblock = 0; + bool flush = false; + long maxmsg; + long msgsize; + struct mq_attr attr = { 0 }; + bool setopts = false; int oflag; + bool opt_o_creat = true; bool opt_o_excl = false; +#ifdef O_CLOEXEC + bool opt_o_cloexec = true; +#endif mode_t opt_mode = 0666; mqd_t mqd; int _errno; @@ -55,10 +68,6 @@ static int xioopen_posixmq( bool with_intv = false; int result = 0; - if (!xioparms.experimental) { - Error1("%s: use option --experimental to acknowledge unmature state", argv[0]); - return STAT_NORETRY; - } if (argc != 2) { xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); return STAT_NORETRY; @@ -77,7 +86,10 @@ static int xioopen_posixmq( with_intv = true; } } - + if (dirs == XIO_RDWR) { + /* Bidirectional ADDRESS in unidirectional mode? Adapt dirs */ + dirs = (xioflags & XIO_ACCMODE); + } retropt_int(opts, OPT_MAX_CHILDREN, &maxchildren); if (! dofork && maxchildren) { Error("option max-children not allowed without option fork"); @@ -94,8 +106,54 @@ static int xioopen_posixmq( Error1("strdup(\"%s\"): out of memory", name); } - retropt_bool(opts, OPT_O_EXCL, &opt_o_excl); - retropt_mode(opts, OPT_PERM, &opt_mode); + retropt_bool(opts, OPT_O_CREAT, &opt_o_creat); + retropt_bool(opts, OPT_O_EXCL, &opt_o_excl); +#ifdef O_CLOEXEC + retropt_bool(opts, OPT_O_CLOEXEC, &opt_o_cloexec); +#endif + retropt_mode(opts, OPT_PERM, &opt_mode); + retropt_bool(opts, OPT_POSIXMQ_FLUSH, &flush); + retropt_long(opts, OPT_POSIXMQ_MAXMSG, &maxmsg) || + (setopts = true); + retropt_long(opts, OPT_POSIXMQ_MSGSIZE, &msgsize) || + (setopts = true); + + /* When just one of mq-maxmsg and mq-msgsize options has been provided, + we must nevertheless set the other option value in struct mq_attr. + For this we have to find the default, read it from /proc fs */ + if (setopts) { + int pfd; + const static char *PROC_MAXMSG = "/proc/sys/fs/mqueue/msg_default"; + const static char *PROC_MSGSIZE = "/proc/sys/fs/mqueue/msgsize_default"; + char buff[21]; /* fit a 64bit num in decimal */ + ssize_t bytes; + + if (maxmsg == 0) { + if ((pfd = Open(PROC_MAXMSG, O_RDONLY, 0)) < 0) { + Warn2("open(\"%s\", O_RDONLY, 0): %s", PROC_MAXMSG, strerror(errno)); + } else if ((bytes = Read(pfd, buff, sizeof(buff)-1)) < 0) { + Warn4("read(%d /* \"%s\" */, buff, "F_Zd"): %s", + pfd, PROC_MAXMSG, sizeof(buff)-1, strerror (errno)); + Close(pfd); + } else { + sscanf(buff, "%ld", &maxmsg); + Close(pfd); + } + } + + if (msgsize == 0) { + if ((pfd = Open(PROC_MSGSIZE, O_RDONLY, 0)) < 0) { + Warn2("open(\"%s\", O_RDONLY, 0): %s", PROC_MSGSIZE, strerror(errno)); + } else if ((bytes = Read(pfd, buff, sizeof(buff)-1)) < 0) { + Warn4("read(%d /* \"%s\" */, buff, "F_Zd"): %s", + pfd, PROC_MSGSIZE, sizeof(buff)-1, strerror (errno)); + Close(pfd); + } else { + sscanf(buff, "%ld", &msgsize); + Close(pfd); + } + } + } retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early); if (opt_unlink_early) { @@ -106,26 +164,65 @@ static int xioopen_posixmq( sfd->howtoend = END_CLOSE; sfd->dtype = XIODATA_POSIXMQ | oneshot; - oflag = O_CREAT; - if (opt_o_excl) oflag |= O_EXCL; + oflag = 0; + if (opt_o_creat) oflag |= O_CREAT; + if (opt_o_excl) oflag |= O_EXCL; +#ifdef O_CLOEXEC + if (opt_o_cloexec) oflag |= O_CLOEXEC; /* does not seem to work (Ubuntu-20) */ +#endif switch (dirs) { case XIO_RDWR: oflag |= O_RDWR; break; case XIO_RDONLY: oflag |= O_RDONLY; break; case XIO_WRONLY: oflag |= O_WRONLY; break; } + if (retropt_bool(opts, OPT_O_NONBLOCK, &nonblock) >= 0 && nonblock) + oflag |= O_NONBLOCK; + + if (flush) { + if (_posixmq_flush(sfd) != STAT_OK) + return STAT_NORETRY; + } /* Now open the message queue */ - Debug3("mq_open(\"%s\", %d, "F_mode", NULL)", name, oflag, opt_mode); - mqd = mq_open(name, oflag, opt_mode, NULL); + if (setopts) { + attr.mq_maxmsg = maxmsg; + attr.mq_msgsize = msgsize; + Debug8("%s: mq_open(\"%s\", "F_mode", "F_mode", {flags=%ld, maxmsg=%ld, msgsize=%ld, curmsgs=%ld} )", argv[0], name, oflag, opt_mode, attr.mq_flags, attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs); + } else { + Debug4("%s: mq_open(\"%s\", "F_mode", "F_mode", NULL)", argv[0], name, oflag, opt_mode); + } + mqd = mq_open(name, oflag, opt_mode, setopts ? &attr : NULL); _errno = errno; Debug1("mq_open() -> %d", mqd); if (mqd < 0) { - Error3("%s: mq_open(\"%s\"): %s", argv[0], name, strerror(errno)); + if (setopts) + Error9("%s: mq_open(\"%s\", "F_mode", "F_mode", {flags=%ld, maxmsg=%ld, msgsize=%ld, curmsgs=%ld} ): %s", argv[0], name, oflag, opt_mode, attr.mq_flags, attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs, strerror(errno)); + else + Error5("%s: mq_open(\"%s\", "F_mode", "F_mode", NULL): %s", argv[0], name, oflag, opt_mode, strerror(errno)); errno = _errno; return STAT_RETRYLATER; } + /* applyopts_cloexec(mqd, opts); */ /* does not seem to work too (Ubuntu-20) */ sfd->fd = mqd; + Debug1("mq_getattr(%d, ...)", mqd); + if (mq_getattr(mqd, &attr) < 0) { + Warn4("mq_getattr(%d[\"%s\"], %p): %s", + mqd, sfd->para.posixmq.name, &attr, strerror(errno)); + mq_close(mqd); + return STAT_NORETRY; + } + Info5("POSIXMQ queue \"%s\" attrs: { flags=%ld, maxmsg=%ld, msgsize=%ld, curmsgs=%ld }", + name, attr.mq_flags, attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs); + if (setopts) { + if (attr.mq_maxmsg != maxmsg) + Warn2("mq_open(): requested maxmsg=%ld, but result is %ld", + maxmsg, attr.mq_maxmsg); + if (attr.mq_msgsize != msgsize) + Warn2("mq_open(): requested msgsize=%ld, but result is %ld", + msgsize, attr.mq_msgsize); + } + if (!dofork && !oneshot) { return STAT_OK; } @@ -155,6 +252,8 @@ static int xioopen_posixmq( do { struct pollfd pollfd; + if (oflag & O_NONBLOCK) + break; pollfd.fd = sfd->fd; pollfd.events = (dirs==XIO_RDONLY?POLLIN:POLLOUT); if (xiopoll(&pollfd, 1, NULL) > 0) { @@ -231,6 +330,81 @@ static int xioopen_posixmq( } +/* With option flush try to open the queue and "consume" its current contents */ +static int _posixmq_flush( + struct single *sfd) +{ + mqd_t mqd; + struct mq_attr attr; + void *buff; + size_t bufsiz; + int _errno; + int p = 0; /* number of messages flushed */ + size_t b = 0; /* number of bytes flushed */ + + Info1("flushing POSIXMQ queue \"%s\"", sfd->para.posixmq.name); + Debug1("mq_open(\"%s\", O_RDONLY|O_NONBLOCK, 0, NULL)", + sfd->para.posixmq.name); + mqd = mq_open(sfd->para.posixmq.name, O_RDONLY|O_NONBLOCK, 0, NULL); + _errno = errno; + Debug1("mq_open() -> %d", mqd); + if (mqd < 0 && _errno == ENOENT) { + Info("this queue does not exist, no need to flush it"); + return STAT_OK; + } + if (mqd < 0) { + Warn2("mq_open(\"%s\", ...): %s", sfd->para.posixmq.name, + strerror(_errno)); + return STAT_NORETRY; + } + + Debug1("mq_getattr(%d, ...)", mqd); + if (mq_getattr(mqd, &attr) < 0) { + Warn4("mq_getattr(%d[\"%s\"], %p): %s", + mqd, sfd->para.posixmq.name, &attr, strerror(errno)); + mq_close(mqd); + return STAT_NORETRY; + } + if (attr.mq_curmsgs == 0) { + Info1("POSIXMQ \"%s\" is empty", sfd->para.posixmq.name); + mq_close(mqd); + return STAT_OK; + } + bufsiz = attr.mq_msgsize; + if ((buff = Malloc(bufsiz)) == NULL) { + mq_close(mqd); + return STAT_RETRYLATER; + } + + /* Now read all messages to null */ + while (true) { + ssize_t bytes; + + Debug3("mq_receive(mqd=%d, %p, "F_Zu", {} )", mqd, buff, bufsiz); + bytes = mq_receive(mqd, buff, bufsiz, &sfd->para.posixmq.prio); + _errno = errno; + Debug1("mq_receive() -> "F_Zd, bytes); + errno = _errno; + if (bytes == 0 || (bytes < 0 && _errno == EAGAIN)) { + break; + } + if (bytes < 0) { + Warn2("flushing POSIXMQ \"%s\" failed: %s", + sfd->para.posixmq.name, strerror(_errno)); + free(buff); + mq_close(mqd); + return STAT_NORETRY; + } + ++p; + b += bytes; + } + Info3("flushed "F_Zu" bytes in %u packets from queue \"%s\"", b, p, + sfd->para.posixmq.name); + free(buff); + mq_close(mqd); + return STAT_OK; +} + ssize_t xiowrite_posixmq( struct single *sfd, const void *buff, @@ -283,6 +457,9 @@ ssize_t xioclose_posixmq( struct single *sfd) { int res; + + if (sfd->fd < 0) + return 0; Debug1("xioclose_posixmq(): mq_close(%d)", sfd->fd); res = mq_close(sfd->fd); if (res < 0) { diff --git a/xio-posixmq.h b/xio-posixmq.h index 8359696..adf827b 100644 --- a/xio-posixmq.h +++ b/xio-posixmq.h @@ -9,8 +9,12 @@ extern const struct addrdesc xioaddr_posixmq_bidir; extern const struct addrdesc xioaddr_posixmq_read; extern const struct addrdesc xioaddr_posixmq_receive; extern const struct addrdesc xioaddr_posixmq_send; +extern const struct addrdesc xioaddr_posixmq_write; +extern const struct optdesc opt_posixmq_maxmsg; +extern const struct optdesc opt_posixmq_msgsize; extern const struct optdesc opt_posixmq_priority; +extern const struct optdesc opt_posixmq_flush; extern ssize_t xioread_posixmq(struct single *file, void *buff, size_t bufsiz); extern ssize_t xiopending_posixmq(struct single *pipe); diff --git a/xio-progcall.c b/xio-progcall.c index f980ef9..d0b8c1c 100644 --- a/xio-progcall.c +++ b/xio-progcall.c @@ -12,6 +12,7 @@ #include "xio-progcall.h" #include "xio-socket.h" +#include "xio-socketpair.h" /* these options are used by address pty too */ @@ -23,7 +24,7 @@ const struct optdesc opt_ptmx = { "ptmx", NULL, OPT_PTMX, GROUP_P #endif const struct optdesc opt_sitout_eio = { "sitout-eio", NULL, OPT_SITOUT_EIO, GROUP_PTY, PH_OFFSET, TYPE_TIMEVAL, OFUNC_OFFSET, XIO_OFFSETOF(para.exec.sitout_eio), XIO_SIZEOF(para.exec.sitout_eio) }; -#if WITH_EXEC || WITH_SYSTEM +#if WITH_EXEC || WITH_SYSTEM || WITH_SHELL #define MAXPTYNAMELEN 64 @@ -623,7 +624,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ *optsp = popts; return pid; /* indicate parent (main) process */ } -#endif /* WITH_EXEC || WITH_SYSTEM */ +#endif /* WITH_EXEC || WITH_SYSTEM || WITH_SHELL */ int setopt_path(struct opt *opts, char **path) { diff --git a/xio-proxy.c b/xio-proxy.c index 86d86e3..ba82d5d 100644 --- a/xio-proxy.c +++ b/xio-proxy.c @@ -83,18 +83,18 @@ static int xioopen_proxy_connect( xiofile_t *xxfd, const struct addrdesc *addrdesc) { - /* we expect the form: host:host:port */ + /* we expect the form: host:host:port */ struct single *sfd = &xxfd->stream; struct opt *opts0 = NULL; struct proxyvars struct_proxyvars = { 0 }, *proxyvars = &struct_proxyvars; /* variables to be filled with address option values */ bool dofork = false; + int maxchildren = 0; /* */ int pf = PF_UNSPEC; - union sockaddr_union us_sa, *us = &us_sa; - socklen_t uslen = sizeof(us_sa); - struct addrinfo **themarr, *themp; - int i; + struct addrinfo **bindarr = NULL; + struct addrinfo **themarr = NULL; + uint16_t bindport = 0; const char *proxyname; char *proxyport = NULL; const char *targetname, *targetport; int ipproto = IPPROTO_TCP; @@ -112,90 +112,123 @@ static int xioopen_proxy_connect( targetname = argv[2]; targetport = argv[3]; - if (sfd->howtoend == END_UNSPEC) - sfd->howtoend = END_SHUTDOWN; - if (applyopts_single(sfd, opts, PH_INIT) < 0) - return -1; - applyopts(sfd, 1, opts, PH_INIT); - - retropt_int(opts, OPT_SO_TYPE, &socktype); - - retropt_bool(opts, OPT_FORK, &dofork); - if (retropt_string(opts, OPT_PROXYPORT, &proxyport) < 0) { if ((proxyport = strdup(PROXYPORT)) == NULL) { errno = ENOMEM; return -1; } } - result = _xioopen_proxy_prepare(proxyvars, opts, targetname, targetport, - sfd->para.socket.ip.ai_flags); - if (result != STAT_OK) - return result; - - Notice4("opening connection to %s:%u via proxy %s:%s", - proxyvars->targetaddr, proxyvars->targetport, proxyname, proxyport); - - i = 0; - do { /* loop over retries (failed connect and proxy-request attempts) */ - - level = E_INFO; - - result = - _xioopen_ipapp_prepare(opts, &opts0, proxyname, proxyport, - &pf, ipproto, - sfd->para.socket.ip.ai_flags, - &themarr, us, &uslen, - &needbind, &lowport, socktype); + result = + _xioopen_ipapp_init(sfd, xioflags, opts, + &dofork, &maxchildren, + &pf, &socktype, &ipproto); if (result != STAT_OK) return result; - /* Loop over themlist */ - i = 0; - themp = themarr[i++]; - while (themp != NULL) { - Notice4("opening connection to %s:%u via proxy %s:%s", - proxyvars->targetaddr, proxyvars->targetport, proxyname, proxyport); -#if WITH_RETRY - if (sfd->forever || sfd->retry || themarr[i] != NULL) { - level = E_INFO; - } else -#endif /* WITH_RETRY */ - level = E_ERROR; + result = _xioopen_proxy_init(proxyvars, opts, targetname, targetport); + if (result != STAT_OK) + return result; - result = - _xioopen_connect(sfd, - needbind?us:NULL, uslen, - themp->ai_addr, themp->ai_addrlen, - opts, pf?pf:themp->ai_family, socktype, IPPROTO_TCP, lowport, level); - if (result == STAT_OK) - break; - themp = themarr[i++]; - if (themp == NULL) { - result = STAT_RETRYLATER; - } + opts0 = opts; /* save remaining options for each loop */ + opts = NULL; + + Notice4("opening connection to %s:%s via proxy %s:%s", + targetname, targetport, proxyname, proxyport); + + do { /* loop over retries (failed connect and proxy-request attempts) + and/or forks */ + int _errno; + +#if WITH_RETRY + if (sfd->forever || sfd->retry) { + level = E_NOTICE; + } else +#endif /* WITH_RETRY */ + level = E_WARN; + + opts = copyopts(opts0, GROUP_ALL); + + result = + _xioopen_ipapp_prepare(&opts, opts0, proxyname, proxyport, + pf, socktype, ipproto, + sfd->para.socket.ip.ai_flags, + &themarr, &bindarr, &bindport, &needbind, &lowport); switch (result) { case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (sfd->forever || sfd->retry) { - --sfd->retry; + if (sfd->forever || sfd->retry--) { if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL); + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + freeopts(opts); continue; } #endif /* WITH_RETRY */ - default: + /* FALLTHROUGH */ + case STAT_NORETRY: + if (bindarr != NULL) xiofreeaddrinfo(bindarr); xiofreeaddrinfo(themarr); + freeopts(opts); + freeopts(opts0); return result; } - } - xiofreeaddrinfo(themarr); - applyopts(sfd, -1, opts, PH_ALL); - if ((result = _xio_openlate(sfd, opts)) < 0) + result = + _xioopen_proxy_prepare(proxyvars, opts, targetname, targetport, + sfd->para.socket.ip.ai_flags); + switch (result) { + case STAT_OK: break; +#if WITH_RETRY + case STAT_RETRYLATER: + case STAT_RETRYNOW: + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) + Nanosleep(&sfd->intervall, NULL); + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + freeopts(opts); + continue; + } +#endif /* WITH_RETRY */ + /* FALLTHROUGH */ + default: + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + freeopts(opts); + freeopts(opts0); return result; + } + + Notice2("opening connection to proxy %s:%s", proxyname, proxyport); + result = + _xioopen_ipapp_connect(sfd, proxyname, opts, themarr, + needbind, bindarr, bindport, lowport, level); + _errno = errno; + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + switch (result) { + case STAT_OK: break; +#if WITH_RETRY + case STAT_RETRYLATER: + case STAT_RETRYNOW: + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) + Nanosleep(&sfd->intervall, NULL); + freeopts(opts); + continue; + } +#endif /* WITH_RETRY */ + /* FALLTHROUGH */ + default: + Error4("%s:%s:...,proxyport=%s: %s", argv[0], proxyname, proxyport, + _errno?strerror(_errno):"(See above)"); + freeopts(opts0); + freeopts(opts); + return result; + } result = _xioopen_proxy_connect(sfd, proxyvars, level); switch (result) { @@ -204,11 +237,16 @@ static int xioopen_proxy_connect( case STAT_RETRYLATER: case STAT_RETRYNOW: if (sfd->forever || sfd->retry--) { - if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL); + if (result == STAT_RETRYLATER) + Nanosleep(&sfd->intervall, NULL); + freeopts(opts); continue; } #endif /* WITH_RETRY */ + /* FALLTHROUGH */ default: + freeopts(opts); + freeopts(opts0); return result; } @@ -225,21 +263,32 @@ static int xioopen_proxy_connect( } while ((pid = xio_fork(false, level, sfd->shutup)) < 0) { if (sfd->forever || --sfd->retry) { - Nanosleep(&sfd->intervall, NULL); continue; + if (sfd->retry > 0) + --sfd->retry; + Nanosleep(&sfd->intervall, NULL); + freeopts(opts); + continue; } + freeopts(opts); + freeopts(opts0); return STAT_RETRYLATER; } if (pid == 0) { /* child process */ - sfd->forever = false; sfd->retry = 0; + sfd->forever = false; + sfd->retry = 0; break; } /* parent process */ Close(sfd->fd); + /* With and without retry */ Nanosleep(&sfd->intervall, NULL); - dropopts(opts, PH_ALL); - opts = copyopts(opts0, GROUP_ALL); + while (maxchildren > 0 && num_child >= maxchildren) { + Info1("all %d allowed children are active, waiting", maxchildren); + Nanosleep(&sfd->intervall, NULL); + } + freeopts(opts); continue; } else #endif /* WITH_RETRY */ @@ -248,25 +297,25 @@ static int xioopen_proxy_connect( } } while (true); /* end of complete open loop - drop out on success */ + /* Only "active" process breaks (master without fork, or child) */ Notice4("successfully connected to %s:%u via proxy %s:%s", proxyvars->targetaddr, proxyvars->targetport, proxyname, proxyport); - return 0; + result = _xio_openlate(sfd, opts); + freeopts(opts); + freeopts(opts0); + return result; } -int _xioopen_proxy_prepare( +int _xioopen_proxy_init( struct proxyvars *proxyvars, struct opt *opts, const char *targetname, - const char *targetport, - const int ai_flags[2]) { - union sockaddr_union host; - socklen_t socklen = sizeof(host); - int rc; - + const char *targetport) +{ retropt_bool(opts, OPT_IGNORECR, &proxyvars->ignorecr); retropt_bool(opts, OPT_PROXY_RESOLVE, &proxyvars->doresolve); retropt_string(opts, OPT_HTTP_VERSION, &proxyvars->version); @@ -316,6 +365,28 @@ int _xioopen_proxy_prepare( Close(authfd); } + if (!proxyvars->doresolve) { + proxyvars->targetaddr = strdup(targetname); + if (proxyvars->targetaddr == NULL) { + Error1("strdup(\"%s\"): out of memory", targetname); + return STAT_RETRYLATER; + } + } + + return STAT_OK; +} + +int _xioopen_proxy_prepare( + struct proxyvars *proxyvars, + struct opt *opts, + const char *targetname, + const char *targetport, + const int ai_flags[2]) +{ + union sockaddr_union host; + socklen_t socklen = sizeof(host); + int rc; + if (proxyvars->doresolve) { /* currently we only resolve to IPv4 addresses. This is in accordance to RFC 2396; however once it becomes clear how IPv6 addresses should be @@ -325,6 +396,10 @@ int _xioopen_proxy_prepare( &host, &socklen, ai_flags); if (rc != STAT_OK) { proxyvars->targetaddr = strdup(targetname); + if (proxyvars->targetaddr == NULL) { + Error1("strdup(\"%s\"): out of memory", targetname); + return STAT_RETRYLATER; + } } else { #define LEN 16 /* www.xxx.yyy.zzz\0 */ if ((proxyvars->targetaddr = Malloc(LEN)) == NULL) { @@ -337,8 +412,6 @@ int _xioopen_proxy_prepare( ((unsigned char *)&host.ip4.sin_addr.s_addr)[3]); #undef LEN } - } else { - proxyvars->targetaddr = strdup(targetname); } proxyvars->targetport = htons(parseport(targetport, IPPROTO_TCP)); @@ -376,7 +449,7 @@ int _xioopen_proxy_connect(struct single *sfd, * xiosanitize(request, strlen(request), textbuff) = '\0'; Info1("sending \"%s\"", textbuff); /* write errors are assumed to always be hard errors, no retry */ - if (writefull(sfd->fd, request, strlen(request)) < 0) { + if (writefull(sfd->fd, request, strlen(request), NULL) < 0) { Msg4(level, "write(%d, %p, "F_Zu"): %s", sfd->fd, request, strlen(request), strerror(errno)); if (Close(sfd->fd) < 0) { @@ -406,7 +479,7 @@ int _xioopen_proxy_connect(struct single *sfd, *next = '\0'; Info1("sending \"%s\\r\\n\"", header); *next++ = '\r'; *next++ = '\n'; *next++ = '\0'; - if (writefull(sfd->fd, header, strlen(header)) < 0) { + if (writefull(sfd->fd, header, strlen(header), NULL) < 0) { Msg4(level, "write(%d, %p, "F_Zu"): %s", sfd->fd, header, strlen(header), strerror(errno)); if (Close(sfd->fd) < 0) { @@ -419,7 +492,7 @@ int _xioopen_proxy_connect(struct single *sfd, } Info("sending \"\\r\\n\""); - if (writefull(sfd->fd, "\r\n", 2) < 0) { + if (writefull(sfd->fd, "\r\n", 2, NULL) < 0) { Msg2(level, "write(%d, \"\\r\\n\", 2): %s", sfd->fd, strerror(errno)); if (Close(sfd->fd) < 0) { diff --git a/xio-proxy.h b/xio-proxy.h index fee18b7..f7fb2b8 100644 --- a/xio-proxy.h +++ b/xio-proxy.h @@ -25,9 +25,8 @@ extern const struct optdesc opt_proxy_authorization_file; extern const struct addrdesc xioaddr_proxy_connect; +extern int _xioopen_proxy_init(struct proxyvars *proxyvars, struct opt *opts, const char *targetname, const char *targetport); extern int _xioopen_proxy_prepare(struct proxyvars *proxyvars, struct opt *opts, const char *targetname, const char *targetport, const int ai_flags[2]); -int _xioopen_proxy_connect(struct single *xfd, - struct proxyvars *proxyvars, - int level); +extern int _xioopen_proxy_connect(struct single *xfd, struct proxyvars *proxyvars, int level); #endif /* !defined(__xio_proxy_h_included) */ diff --git a/xio-readline.c b/xio-readline.c index 376cd26..69423c0 100644 --- a/xio-readline.c +++ b/xio-readline.c @@ -184,7 +184,7 @@ ssize_t xioread_readline(struct single *pipe, void *buff, size_t bufsiz) { /* we must carriage return, because readline will first print the prompt */ ssize_t writt; - writt = writefull(pipe->fd, "\r", 1); + writt = writefull(pipe->fd, "\r", 1, NULL); if (writt < 0) { Warn2("write(%d, \"\\r\", 1): %s", pipe->fd, strerror(errno)); @@ -204,6 +204,9 @@ ssize_t xioread_readline(struct single *pipe, void *buff, size_t bufsiz) { if (line == NULL) { return 0; /* EOF */ } + if (strlen(line) == 0) { + Write(STDOUT_FILENO, "\n", 1); + } #if _WITH_TERMIOS xiotermios_clrflag(pipe->fd, 3, ECHO); xiotermios_flush(pipe->fd); diff --git a/xio-shell.c b/xio-shell.c index 8a41e21..a06358b 100644 --- a/xio-shell.c +++ b/xio-shell.c @@ -81,7 +81,7 @@ static int xioopen_shell( Setenv("SHELL", shellpath, 1); Info1("executing shell command \"%s\"", string); - Debug3("execl(\"%s\", \"%s\", \"-c\", \"%s\", NULL", + Debug3("execl(\"%s\", \"%s\", \"-c\", \"%s\", NULL)", shellpath, shellname, string); result = execl(shellpath, shellname, "-c", string, (char *)NULL); if (result != 0) { diff --git a/xio-socket.c b/xio-socket.c index 5a7782f..e2c0ab2 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -7,8 +7,6 @@ #include "xiosysincludes.h" -#if _WITH_SOCKET - #include "xioopen.h" #include "xio-ascii.h" #include "xio-socket.h" @@ -30,6 +28,8 @@ #include "xio-tcpwrap.h" +#if _WITH_SOCKET + static int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); static int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); static int xioopen_socket_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); @@ -191,6 +191,8 @@ const struct optdesc opt_setsockopt_int = { "setsockopt-int", "sockopt-int const struct optdesc opt_setsockopt_bin = { "setsockopt-bin", "sockopt-bin", OPT_SETSOCKOPT_BIN, GROUP_SOCKET,PH_CONNECTED, TYPE_INT_INT_BIN, OFUNC_SOCKOPT_GENERIC, 0, 0 }; const struct optdesc opt_setsockopt_string = { "setsockopt-string", "sockopt-string", OPT_SETSOCKOPT_STRING, GROUP_SOCKET,PH_CONNECTED, TYPE_INT_INT_STRING, OFUNC_SOCKOPT_GENERIC, 0, 0 }; const struct optdesc opt_setsockopt_listen = { "setsockopt-listen", "sockopt-listen", OPT_SETSOCKOPT_LISTEN, GROUP_SOCKET,PH_PREBIND, TYPE_INT_INT_BIN, OFUNC_SOCKOPT_GENERIC, 0, 0 }; +const struct optdesc opt_setsockopt_socket = { "setsockopt-socket", "sockopt-sock", OPT_SETSOCKOPT_SOCKET, GROUP_SOCKET,PH_PASTSOCKET, TYPE_INT_INT_BIN, OFUNC_SOCKOPT_GENERIC, 0, 0 }; +const struct optdesc opt_setsockopt_connected = { "setsockopt-connected", "sockopt-conn", OPT_SETSOCKOPT_CONNECTED, GROUP_SOCKET,PH_CONNECTED, TYPE_INT_INT_BIN, OFUNC_SOCKOPT_GENERIC, 0, 0 }; const struct optdesc opt_null_eof = { "null-eof", NULL, OPT_NULL_EOF, GROUP_SOCKET, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(para.socket.null_eof) }; @@ -262,8 +264,13 @@ static int xioopen_socket_connect( sfd->dtype = XIOREAD_STREAM|XIOWRITE_STREAM; socket_init(0, &us); - if (retropt_bind(opts, 0 /*pf*/, socktype, proto, (struct sockaddr *)&us, &uslen, 3, - sfd->para.socket.ip.ai_flags) + if (retropt_bind(opts, pf, socktype, proto, (struct sockaddr *)&us, &uslen, -1, +#if _WITH_IP4 || _WITH_IP6 + sfd->para.socket.ip.ai_flags +#else + NULL +#endif /* _WITH_IP4 || _WITH_IP6 */ + ) != STAT_NOACTION) { needbind = true; us.soa.sa_family = pf; @@ -540,7 +547,12 @@ int xioopen_socket_recvfrom( if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, 0, &sfd->para.socket.range, - sfd->para.socket.ip.ai_flags) +#if _WITH_IP4 || _WITH_IP6 + sfd->para.socket.ip.ai_flags +#else + NULL +#endif /* _WITH_IP4 */ + ) < 0) { free(rangename); return STAT_NORETRY; @@ -626,7 +638,12 @@ int xioopen_socket_recv( if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, 0, &sfd->para.socket.range, - sfd->para.socket.ip.ai_flags) +#if _WITH_IP4 || _WITH_IP6 + sfd->para.socket.ip.ai_flags +#else + NULL +#endif /* _WITH_IP4 */ + ) < 0) { free(rangename); return STAT_NORETRY; @@ -712,7 +729,12 @@ static int xioopen_socket_datagram( /* which reply sockets will accept - determine by range option */ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, 0, &sfd->para.socket.range, - sfd->para.socket.ip.ai_flags) +#if _WITH_IP4 || _WITH_IP6 + sfd->para.socket.ip.ai_flags +#else + NULL +#endif /* _WITH_IP4 */ + ) < 0) { free(rangename); return STAT_NORETRY; @@ -779,13 +801,13 @@ int xiogetpacketinfo(struct single *sfd, int fd) PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECT, PH_CONNECTED, PH_LATE, OFUNC_OFFSET, - OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC + OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_O_CLOEXEC Does not fork, does not retry. Alternate (alt) bind semantics are: with IP sockets: lowport (selects randomly a free port from 640 to 1023) with UNIX and abstract sockets: uses tmpname() to find a free file system entry. - returns 0 on success. + Returns STAT_OK on success, or STAT_RETRYLATER (+errno) on failure. */ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, struct sockaddr *them, size_t themlen, @@ -815,7 +837,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, applyopts_cloexec(sfd->fd, opts); if (xiobind(sfd, us, uslen, opts, pf, alt, level) < 0) { - return -1; + return STAT_RETRYLATER; } applyopts(sfd, -1, opts, PH_CONNECT); @@ -855,6 +877,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, Msg4(level, "xiopoll({%d,POLLOUT|POLLERR},,{"F_tv_sec"."F_tv_usec"): %s", sfd->fd, timeout.tv_sec, timeout.tv_usec, strerror(errno)); Close(sfd->fd); + errno = _errno; return STAT_RETRYLATER; } if (result == 0) { @@ -862,6 +885,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)), strerror(ETIMEDOUT)); Close(sfd->fd); + errno = _errno; return STAT_RETRYLATER; } if (writefd.revents & POLLERR) { @@ -877,15 +901,19 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, sfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)), themlen, strerror(errno)); #endif + _errno = errno; Close(sfd->fd); + errno = _errno; return STAT_RETRYLATER; } /* otherwise OK or network error */ result = Getsockopt(sfd->fd, SOL_SOCKET, SO_ERROR, &err, &errlen); if (result != 0) { + _errno = errno; Msg2(level, "getsockopt(%d, SOL_SOCKET, SO_ERROR, ...): %s", sfd->fd, strerror(err)); Close(sfd->fd); + errno = _errno; return STAT_RETRYLATER; } Debug2("getsockopt(%d, SOL_SOCKET, SO_ERROR, { %d }) -> 0", @@ -895,6 +923,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, sfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)), themlen, strerror(err)); Close(sfd->fd); + errno = err; return STAT_RETRYLATER; } Fcntl_l(sfd->fd, F_SETFL, fcntl_flags); @@ -925,6 +954,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, sfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)), themlen, strerror(errno)); Close(sfd->fd); + errno = _errno; return STAT_RETRYLATER; } } else { /* result >= 0 */ @@ -952,7 +982,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECT, PH_CONNECTED, PH_LATE, OFUNC_OFFSET, - OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC + OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_O_CLOEXEC returns 0 on success. */ int xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, @@ -1052,7 +1082,7 @@ int xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, applies and consumes the following option: PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECTED, PH_LATE OFUNC_OFFSET - OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC + OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_O_CLOEXEC */ int _xioopen_dgram_sendto(/* them is already in xfd->peersa */ union sockaddr_union *us, socklen_t uslen, @@ -1202,6 +1232,7 @@ int _xioopen_dgram_recvfrom(struct single *sfd, int xioflags, } #endif +#if WITH_IP4 || WITH_IP6 /* for generic sockets, this has already been retrieved */ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, pf, &sfd->para.socket.range, @@ -1213,6 +1244,7 @@ int _xioopen_dgram_recvfrom(struct single *sfd, int xioflags, free(rangename); sfd->para.socket.dorange = true; } +#endif /* WITH_IP4 || WITH_IP6 */ #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP xio_retropt_tcpwrap(sfd, opts); @@ -1424,6 +1456,7 @@ int _xioopen_dgram_recv(struct single *sfd, int xioflags, } #endif +#if WITH_IP4 || WITH_IP6 if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, pf, &sfd->para.socket.range, sfd->para.socket.ip.ai_flags) @@ -1434,6 +1467,7 @@ int _xioopen_dgram_recv(struct single *sfd, int xioflags, free(rangename); sfd->para.socket.dorange = true; } +#endif /* WITH_IP4 || WITH_IP6 */ #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP xio_retropt_tcpwrap(sfd, opts); @@ -1449,7 +1483,10 @@ int _xioopen_dgram_recv(struct single *sfd, int xioflags, return STAT_OK; } +#endif /* _WITH_SOCKET */ + +#if _WITH_SOCKET || _WITH_SOCKETPAIR int retropt_socket_pf(struct opt *opts, int *pf) { char *pfname; @@ -1478,8 +1515,11 @@ int retropt_socket_pf(struct opt *opts, int *pf) { } return -1; } +#endif /* _WITH_SOCKET || _WITH_SOCKETPAIR */ +#if _WITH_SOCKET + /* This function calls recvmsg(..., MSG_PEEK, ...) to obtain information about the arriving packet, thus it does not "consume" the packet. In msgh the msg_name pointer must refer to an (empty) sockaddr storage. @@ -1651,7 +1691,7 @@ int xiocheckpeer(xiosingle_t *sfd, char infobuff[256]; int result; -#if WITH_IP4 +#if WITH_IP4 || WITH_IP6 if (sfd->para.socket.dorange) { if (pa == NULL) { return -1; } if (xiocheckrange(pa, &sfd->para.socket.range) < 0) { @@ -1736,7 +1776,7 @@ int xiocheckpeer(xiosingle_t *sfd, #if HAVE_STRUCT_CMSGHDR -/* converts the ancillary message in *cmsg into a form useable for further +/* Converts the ancillary message in *cmsg into a form usable for further processing. knows the specifics of common message types. returns the number of resulting syntax elements in *num returns a sequence of \0 terminated type strings in *typbuff @@ -1957,7 +1997,7 @@ int xioparserange( return -1; } /* we have parsed the address and mask; now we make sure that the stored - address has 0 where mask is 0, to simplify comparisions */ + address has 0 where mask is 0, to simplify comparisons */ switch (pf) { #if WITH_IP4 case PF_INET: @@ -2055,15 +2095,12 @@ int xiosetsockaddrenv(const char *lr, # undef XIOSOCKADDRENVLEN } -#endif /* _WITH_SOCKET */ - -/* these do sockets internally */ +/* These do sockets internally */ /* retrieves options so-type and so-prototype from opts, calls socket, and ev. generates an appropriate error message. - returns 0 on success or -1 if an error occurred. */ -int -xiosocket(struct opt *opts, int pf, int socktype, int proto, int msglevel) { + returns 0 on success or -1 (and errno) if an error occurred. */ +int xiosocket(struct opt *opts, int pf, int socktype, int proto, int msglevel) { int result; retropt_int(opts, OPT_SO_TYPE, &socktype); @@ -2080,24 +2117,6 @@ xiosocket(struct opt *opts, int pf, int socktype, int proto, int msglevel) { return result; } -/* retrieves options so-type and so-prototype from opts, calls socketpair, and - ev. generates an appropriate error message. - returns 0 on success or -1 if an error occurred. */ -int -xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]) { - int result; - - retropt_int(opts, OPT_SO_TYPE, &socktype); - retropt_int(opts, OPT_SO_PROTOTYPE, &proto); - result = Socketpair(pf, socktype, proto, sv); - if (result < 0) { - Error5("socketpair(%d, %d, %d, %p): %s", - pf, socktype, proto, sv, strerror(errno)); - return -1; - } - return result; -} - /* Binds a socket to a socket address. Handles IP (internet protocol), UNIX domain, Linux abstract UNIX domain. The bind address us may be NULL in which case no bind() happens, except with @@ -2106,6 +2125,7 @@ xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]) { with IP sockets: lowport (selects randomly a free port from 640 to 1023) with UNIX and abstract sockets: uses a method similar to tmpname() to find a free file system entry. + On success returns STAT_OK, otherwise errno is set. */ int xiobind( struct single *sfd, @@ -2142,18 +2162,20 @@ int xiobind( usrname = strndup(us->un.sun_path, sizeof(us->un.sun_path)); if (usrname == NULL) { int _errno = errno; - Error2("strndup(\"%s\", "F_Zu"): out of memory", + Msg2(level, "strndup(\"%s\", "F_Zu"): out of memory", us->un.sun_path, sizeof(us->un.sun_path)); errno = _errno; - return -1; + return STAT_RETRYLATER; } } do { /* loop over tempnam bind() attempts */ sockname = xio_tempnam(usrname, abstract); if (sockname == NULL) { + int _errno = errno; Error2("tempnam(\"%s\"): %s", usrname, strerror(errno)); free(usrname); + errno = _errno; return -1; } strncpy(us->un.sun_path+(abstract?1:0), sockname, sizeof(us->un.sun_path)); @@ -2167,8 +2189,10 @@ int xiobind( infobuff, sizeof(infobuff)), uslen, strerror(errno)); if (errno != EADDRINUSE) { + int _errno = errno; free(usrname); Close(sfd->fd); + errno = _errno; return STAT_RETRYLATER; } } else { @@ -2181,10 +2205,12 @@ int xiobind( if (us != NULL) { if (Bind(sfd->fd, &us->soa, uslen) < 0) { + int _errno = errno; Msg4(level, "bind(%d, {%s}, "F_Zd"): %s", sfd->fd, sockaddr_info(&us->soa, uslen, infobuff, sizeof(infobuff)), uslen, strerror(errno)); Close(sfd->fd); + errno = _errno; return STAT_RETRYLATER; } applyopts_named(us->un.sun_path, opts, PH_PREOPEN); @@ -2206,8 +2232,12 @@ int xiobind( if (us) { sinp = us; } else { - if (pf == AF_INET) { + if (0) { + ; +#if WITH_IP4 + } else if (pf == AF_INET) { socket_in_init(&sin.ip4); +#endif #if WITH_IP6 } else { socket_in6_init(&sin.ip6); @@ -2252,12 +2282,14 @@ int xiobind( do { /* loop over lowport bind() attempts */ *port = htons(i); if (Bind(sfd->fd, &sinp->soa, sizeof(*sinp)) < 0) { + int _errno = errno; Msg4(errno==EADDRINUSE?E_INFO:level, "bind(%d, {%s}, "F_Zd"): %s", sfd->fd, sockaddr_info(&sinp->soa, sizeof(*sinp), infobuff, sizeof(infobuff)), sizeof(*sinp), strerror(errno)); - if (errno != EADDRINUSE) { + if (_errno != EADDRINUSE) { Close(sfd->fd); + errno = _errno; return STAT_RETRYLATER; } } else { @@ -2266,8 +2298,8 @@ int xiobind( --i; if (i < XIO_IPPORT_LOWER) i = IPPORT_RESERVED-1; if (i == N) { Msg(level, "no low port available"); - /*errno = EADDRINUSE; still assigned */ Close(sfd->fd); + errno = EADDRINUSE; return STAT_RETRYLATER; } } while (i != N); @@ -2278,24 +2310,26 @@ int xiobind( if (us) { applyopts(sfd, sfd->fd, opts, PH_BIND); if (Bind(sfd->fd, &us->soa, uslen) < 0) { + int _errno = errno; Msg4(level, "bind(%d, {%s}, "F_Zd"): %s", sfd->fd, sockaddr_info(&us->soa, uslen, infobuff, sizeof(infobuff)), uslen, strerror(errno)); Close(sfd->fd); + errno = _errno; return STAT_RETRYLATER; } } } applyopts(sfd, -1, opts, PH_PASTBIND); - return 0; + return STAT_OK; } /* Handles the SO_REUSEADDR socket option for TCP LISTEN addresses depending on Socat option so-reuseaddr: Option not applied: set it to 1 Option applied with a value: set it to the value - Option applied eith empty value "so-reuseaddr=": do not call setsockopt() for + Option applied with empty value "so-reuseaddr=": do not call setsockopt() for SO_REUSEADDR Return 0 on success, or -1 with errno when an error occurred. */ @@ -2303,15 +2337,25 @@ int xiosock_reuseaddr(int fd, int ipproto, struct opt *opts) { union integral val; union integral notnull; + int result; int _errno; val.u_int = 0; notnull.u_bool = false; +#if WITH_TCP if (ipproto == IPPROTO_TCP) { val.u_int = 1; notnull.u_bool = true; } - retropt_2integrals(opts, OPT_SO_REUSEADDR, &val, ¬null); +#endif /* WITH_TCP */ + result = retropt_2integrals(opts, OPT_SO_REUSEADDR, &val, ¬null); +#if WITH_TCP + if (ipproto == IPPROTO_TCP && result < 0) { + Info("Setting SO_REUSADDR on TCP listen socket implicitly"); + val.u_int = 1; + notnull.u_bool = true; + } +#endif /* WITH_TCP */ if (notnull.u_bool) { if (Setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val.u_int, sizeof(int)) != 0) { @@ -2324,3 +2368,6 @@ int xiosock_reuseaddr(int fd, int ipproto, struct opt *opts) } return 0; } + +#endif /* _WITH_SOCKET */ + diff --git a/xio-socket.h b/xio-socket.h index 2064ed3..2ecb28b 100644 --- a/xio-socket.h +++ b/xio-socket.h @@ -83,6 +83,8 @@ extern const struct optdesc opt_setsockopt_bin; extern const struct optdesc opt_setsockopt_string; extern const struct optdesc opt_setsockopt_listen; extern const struct optdesc opt_null_eof; +extern const struct optdesc opt_setsockopt_socket; +extern const struct optdesc opt_setsockopt_connected; extern @@ -135,8 +137,6 @@ extern int xioparserange(const char *rangename, int pf, struct xiorange *range, extern int xiosocket(struct opt *opts, int pf, int socktype, int proto, int level); -extern int -xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]); extern int xiosock_reuseaddr(int fd, int ipproto, struct opt *opts); #endif /* !defined(__xio_socket_h_included) */ diff --git a/xio-socketpair.c b/xio-socketpair.c index 0da0c99..e062a44 100644 --- a/xio-socketpair.c +++ b/xio-socketpair.c @@ -95,3 +95,26 @@ static int xioopen_socketpair( } #endif /* WITH_SOCKETPAIR */ + + +#if _WITH_SOCKETPAIR + +/* retrieves options so-type and so-prototype from opts, calls socketpair, and + ev. generates an appropriate error message. + returns 0 on success or -1 if an error occurred. */ +int +xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]) { + int result; + + retropt_int(opts, OPT_SO_TYPE, &socktype); + retropt_int(opts, OPT_SO_PROTOTYPE, &proto); + result = Socketpair(pf, socktype, proto, sv); + if (result < 0) { + Error5("socketpair(%d, %d, %d, %p): %s", + pf, socktype, proto, sv, strerror(errno)); + return -1; + } + return result; +} + +#endif /* _WITH_SOCKETPAIR */ diff --git a/xio-socketpair.h b/xio-socketpair.h index 2f92f70..5822798 100644 --- a/xio-socketpair.h +++ b/xio-socketpair.h @@ -7,4 +7,6 @@ const extern struct addrdesc xioaddr_socketpair; +extern int xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]); + #endif /* !defined(__xio_socketpair_h_included) */ diff --git a/xio-socks.c b/xio-socks.c index d5234cb..ea0805c 100644 --- a/xio-socks.c +++ b/xio-socks.c @@ -6,14 +6,16 @@ #include "xiosysincludes.h" -#if WITH_SOCKS4 || WITH_SOCKS4A - #include "xioopen.h" #include "xio-ascii.h" #include "xio-socket.h" #include "xio-ip.h" #include "xio-ipapp.h" +#define SOCKSPORT "1080" + +#if WITH_SOCKS4 || WITH_SOCKS4A + #include "xio-socks.h" @@ -24,7 +26,6 @@ enum { SOCKS_CD_IDENTFAILED } ; -#define SOCKSPORT "1080" #define BUFF_LEN (SIZEOF_STRUCT_SOCKS4+512) static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc); @@ -53,13 +54,12 @@ static int xioopen_socks4_connect( int pf = PF_UNSPEC; int ipproto = IPPROTO_TCP; bool dofork = false; - union sockaddr_union us_sa, *us = &us_sa; - socklen_t uslen = sizeof(us_sa); - struct addrinfo **themarr, *themp; - int i; + int maxchildren = 0; + struct addrinfo **bindarr = NULL; + struct addrinfo **themarr = NULL; + uint16_t bindport = 0; bool needbind = false; bool lowport = false; - char infobuff[256]; unsigned char buff[BUFF_LEN]; struct socks4 *sockhead = (struct socks4 *)buff; size_t buflen = sizeof(buff); @@ -75,41 +75,43 @@ static int xioopen_socks4_connect( targetname = argv[2]; targetport = argv[3]; - if (sfd->howtoend == END_UNSPEC) - sfd->howtoend = END_SHUTDOWN; - if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1; - applyopts(sfd, 1, opts, PH_INIT); - - retropt_int(opts, OPT_SO_TYPE, &socktype); - - retropt_bool(opts, OPT_FORK, &dofork); - - result = _xioopen_socks4_prepare(targetport, opts, &socksport, sockhead, &buflen); + /* Apply and retrieve some options */ + result = _xioopen_ipapp_init(sfd, xioflags, opts, + &dofork, &maxchildren, + &pf, &socktype, &ipproto); if (result != STAT_OK) return result; + result = _xioopen_socks4_init(targetport, opts, &socksport, sockhead, + &buflen); + if (result != STAT_OK) + return result; + + opts0 = opts; /* save remaining options for each loop */ + opts = NULL; + Notice5("opening connection to %s:%u via socks4 server %s:%s as user \"%s\"", - targetname, - ntohs(sockhead->port), + targetname, ntohs(sockhead->port), sockdname, socksport, sockhead->userid); - i = 0; - do { /* loop over retries (failed connect and socks-request attempts) */ + do { /* loop over retries (failed connect and socks-request attempts) + and/or forks */ + int _errno; - level = E_INFO; +#if WITH_RETRY + if (sfd->forever || sfd->retry) { + level = E_NOTICE; + } else +#endif /* WITH_RETRY */ + level = E_WARN; + + opts = copyopts(opts0, GROUP_ALL); result = - _xioopen_ipapp_prepare(opts, &opts0, sockdname, socksport, - &pf, ipproto, + _xioopen_ipapp_prepare(&opts, opts0, sockdname, socksport, + pf, socktype, ipproto, sfd->para.socket.ip.ai_flags, - &themarr, us, &uslen, - &needbind, &lowport, socktype); - - /* we try to resolve the target address _before_ connecting to the socks - server: this avoids unnecessary socks connects and timeouts */ - result = - _xioopen_socks4_connect0(sfd, targetname, socks4a, sockhead, - (ssize_t *)&buflen, level); + &themarr, &bindarr, &bindport, &needbind, &lowport); switch (result) { case STAT_OK: break; #if WITH_RETRY @@ -118,60 +120,78 @@ static int xioopen_socks4_connect( if (sfd->forever || sfd->retry--) { if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL); + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + freeopts(opts); continue; } #endif /* WITH_RETRY */ - default: + /* FALLTHROUGH */ + case STAT_NORETRY: + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + freeopts(opts); + freeopts(opts0); return result; } - /* loop over themarr */ - i = 0; - themp = themarr[i++]; - while (themp != NULL) { - Notice1("opening connection to %s", - sockaddr_info(themp->ai_addr, themp->ai_addrlen, - infobuff, sizeof(infobuff))); -#if WITH_RETRY - if (sfd->forever || sfd->retry || themarr[i] != NULL) { - level = E_INFO; - } else -#endif /* WITH_RETRY */ - level = E_ERROR; - - /* this cannot fork because we retrieved fork option above */ - result = - _xioopen_connect(sfd, - needbind?us:NULL, uslen, - themp->ai_addr, themp->ai_addrlen, - opts, pf?pf:themp->ai_family, socktype, IPPROTO_TCP, lowport, level); - if (result == STAT_OK) - break; - themp = themarr[i++]; - if (themp == NULL) - result = STAT_RETRYLATER; - } + /* we try to resolve the target address _before_ connecting to the socks + server: this may avoid unnecessary connects and timeouts */ + result = + _xioopen_socks4_prepare(sfd, targetname, socks4a, sockhead, + (ssize_t *)&buflen, level); switch (result) { case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (sfd->forever || sfd->retry) { - --sfd->retry; + if (sfd->forever || sfd->retry--) { if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL); + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + freeopts(opts); continue; } #endif /* WITH_RETRY */ + /* FALLTHROUGH */ default: + if (bindarr != NULL) xiofreeaddrinfo(bindarr); xiofreeaddrinfo(themarr); + freeopts(opts); + freeopts(opts0); return result; } - xiofreeaddrinfo(themarr); - applyopts(sfd, -1, opts, PH_ALL); - if ((result = _xio_openlate(sfd, opts)) < 0) + Notice2("opening connection to sockd %s:%s", sockdname, socksport); + result = + _xioopen_ipapp_connect(sfd, sockdname, opts, themarr, + needbind, bindarr, bindport, lowport, level); + _errno = errno; + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + switch (result) { + case STAT_OK: break; +#if WITH_RETRY + case STAT_RETRYLATER: + case STAT_RETRYNOW: + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) { + Nanosleep(&sfd->intervall, NULL); + } + freeopts(opts); + continue; + } +#endif /* WITH_RETRY */ + /* FALLTHROUGH */ + default: + errno = _errno; + Error4("%s:%s:...,socksport=%s: %s", argv[0], sockdname, socksport, + _errno?strerror(_errno):"(See above)"); + freeopts(opts0); + freeopts(opts); return result; + } result = _xioopen_socks4_connect(sfd, sockhead, buflen, level); switch (result) { @@ -180,11 +200,16 @@ static int xioopen_socks4_connect( case STAT_RETRYLATER: case STAT_RETRYNOW: if (sfd->forever || sfd->retry--) { - if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL); + if (result == STAT_RETRYLATER) + Nanosleep(&sfd->intervall, NULL); + freeopts(opts); continue; } #endif /* WITH_RETRY */ + /* FALLTHROUGH */ default: + freeopts(opts); + freeopts(opts0); return result; } @@ -201,10 +226,13 @@ static int xioopen_socks4_connect( so Notice is too weak */ } while ((pid = xio_fork(false, level, sfd->shutup)) < 0) { - if (sfd->forever || --sfd->retry) { + if (sfd->forever || sfd->retry--) { Nanosleep(&sfd->intervall, NULL); + freeopts(opts); continue; } + freeopts(opts); + freeopts(opts0); return STAT_RETRYLATER; } @@ -216,8 +244,13 @@ static int xioopen_socks4_connect( /* parent process */ Close(sfd->fd); + /* with and without retry */ Nanosleep(&sfd->intervall, NULL); - dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); + while (maxchildren > 0 && num_child >= maxchildren) { + Info1("all %d allowed children are active, waiting", maxchildren); + Nanosleep(&sfd->intervall, NULL); + } + freeopts(opts); continue; } else #endif /* WITH_RETRY */ @@ -226,9 +259,19 @@ static int xioopen_socks4_connect( } } while (true); /* end of complete open loop - drop out on success */ - return 0; + /* only "active" process breaks (master without fork, or child) */ + + Notice4("successfully connected to %s:%s via sockd %s:%s", + targetname, targetport, sockdname, socksport); + + result = _xio_openlate(sfd, opts); + freeopts(opts); + freeopts(opts0); + return result; } +#endif /* WITH_SOCKS4 || WITH_SOCKS4A */ +#if WITH_SOCKS4 || WITH_SOCKS4A || WITH_SOCKS5 int _xioopen_opt_socksport( struct opt *opts, @@ -236,7 +279,8 @@ int _xioopen_opt_socksport( { struct servent *se; - if (retropt_string(opts, OPT_SOCKSPORT, socksport) < 0) { + if (retropt_string(opts, OPT_SOCKSPORT, socksport) < 0 && + *socksport == NULL) { if ((se = getservbyname("socks", "tcp")) != NULL) { Debug1("\"socks/tcp\" resolves to %u", ntohs(se->s_port)); if ((*socksport = Malloc(6)) == NULL) { @@ -253,8 +297,16 @@ int _xioopen_opt_socksport( return 0; } +#endif /* WITH_SOCKS4 || WITH_SOCKS4A || WITH_SOCKS5 */ +#if WITH_SOCKS4 || WITH_SOCKS4A -int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **socksport, struct socks4 *sockhead, size_t *headlen) { +int _xioopen_socks4_init( + const char *targetport, + struct opt *opts, + char **socksport, + struct socks4 *sockhead, + size_t *headlen) +{ char *userid; /* generate socks header - points to final target */ @@ -280,14 +332,14 @@ int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **soc /* called within retry/fork loop, before connect() */ -int - _xioopen_socks4_connect0(struct single *sfd, - const char *hostname, /* socks target host */ - int socks4a, - struct socks4 *sockhead, - ssize_t *headlen, /* get available space, - return used length*/ - int level) { +int _xioopen_socks4_prepare( + struct single *sfd, + const char *hostname, /* socks target host */ + int socks4a, + struct socks4 *sockhead, + ssize_t *headlen, /* get available space, return used length*/ + int level) +{ int result; if (!socks4a) { @@ -364,7 +416,7 @@ int _xioopen_socks4_connect(struct single *sfd, } } #endif /* WITH_MSGLEVEL <= E_DEBUG */ - if (writefull(sfd->fd, sockhead, headlen) < 0) { + if (writefull(sfd->fd, sockhead, headlen, NULL) < 0) { Msg4(level, "write(%d, %p, "F_Zu"): %s", sfd->fd, sockhead, headlen, strerror(errno)); if (Close(sfd->fd) < 0) { @@ -429,16 +481,7 @@ int _xioopen_socks4_connect(struct single *sfd, switch (replyhead->action) { case SOCKS_CD_GRANTED: /* Notice("socks: connect request succeeded"); */ -#if 0 - if (Getsockname(sfd->fd, (struct sockaddr *)&us, &uslen) < 0) { - Warn4("getsockname(%d, %p, {%d}): %s", - sfd->fd, &us, uslen, strerror(errno)); - } - Notice1("successfully connected from %s via socks4", - sockaddr_info((struct sockaddr *)&us, infobuff, sizeof(infobuff))); -#else Notice("successfully connected via socks4"); -#endif break; case SOCKS_CD_FAILED: diff --git a/xio-socks.h b/xio-socks.h index b089ec2..f5abfb9 100644 --- a/xio-socks.h +++ b/xio-socks.h @@ -10,9 +10,9 @@ struct socks4 { uint8_t action; uint16_t port; uint32_t dest; - char userid[1]; /* just to have access via this struct */ + char userid[0]; /* just to have access via this struct */ } ; -#define SIZEOF_STRUCT_SOCKS4 8 +#define SIZEOF_STRUCT_SOCKS4 ((size_t)&((struct socks4 *)0)->userid) extern const struct optdesc opt_socksport; extern const struct optdesc opt_socksuser; @@ -21,15 +21,8 @@ extern const struct addrdesc xioaddr_socks4_connect; extern const struct addrdesc xioaddr_socks4a_connect; extern int _xioopen_opt_socksport(struct opt *opts, char **socksport); -extern int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **socksport, struct socks4 *sockhead, size_t *headlen); -extern int - _xioopen_socks4_connect0(struct single *xfd, - const char *hostname, /* socks target host */ - int socks4a, - struct socks4 *sockhead, - ssize_t *headlen, /* get available space, - return used length*/ - int level); +extern int _xioopen_socks4_init(const char *targetport, struct opt *opts, char **socksport, struct socks4 *sockhead, size_t *headlen); +extern int _xioopen_socks4_prepare(struct single *xfd, const char *hostname, int socks4a, struct socks4 *sockhead, ssize_t *headlen, int level); extern int _xioopen_socks4_connect(struct single *xfd, struct socks4 *sockhead, size_t headlen, diff --git a/xio-socks5.c b/xio-socks5.c index 8543881..27ae1b1 100644 --- a/xio-socks5.c +++ b/xio-socks5.c @@ -53,7 +53,7 @@ static int xioopen_socks5(int argc, const char *argv[], struct opt *opts, int xi const struct addrdesc xioaddr_socks5_connect = { "SOCKS5-CONNECT", 1+XIO_RDWR, xioopen_socks5, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_IP_SOCKS|GROUP_CHILD|GROUP_RETRY, SOCKS5_COMMAND_CONNECT, 0, 0 HELP(":<socks-server>[:<socks-port>]:<target-host>:<target-port>") }; -const struct addrdesc xioaddr_socks5_listen = { "SOCKS5-LISTEN", 1+XIO_RDWR, xioopen_socks5, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_CHILD|GROUP_RETRY, SOCKS5_COMMAND_BIND, 0, 0 HELP(":<socks-server>[:<socks-port>]:<listen-host>:<listen-port>") }; +const struct addrdesc xioaddr_socks5_listen = { "SOCKS5-LISTEN", 1+XIO_RDWR, xioopen_socks5, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_IP_SOCKS|GROUP_CHILD|GROUP_RETRY, SOCKS5_COMMAND_BIND, 0, 0 HELP(":<socks-server>[:<socks-port>]:<listen-host>:<listen-port>") }; static const char * _xioopen_socks5_strerror(uint8_t r) { @@ -136,7 +136,7 @@ static int _xioopen_socks5_handshake(struct single *sfd, int level) } #endif - if (writefull(sfd->fd, client_hello, client_hello_size) < 0) { + if (writefull(sfd->fd, client_hello, client_hello_size, NULL) < 0) { Msg4(level, "write(%d, %p, %d): %s", sfd->fd, client_hello, client_hello_size, strerror(errno)); @@ -188,6 +188,8 @@ static int _xioopen_socks5_handshake(struct single *sfd, int level) return STAT_RETRYLATER; } + Debug2("received SOCKS5 server hello %02x %02x", + server_hello_ptr[0], server_hello_ptr[1]); Info2("received SOCKS5 server hello version=%d method=%d", server_hello.version, server_hello.method); @@ -332,6 +334,12 @@ static int _xioopen_socks5_read_reply( } return STAT_RETRYLATER; } + Debug5("received SOCKS5 reply %02x %02x %02x %02x %02x", + ((unsigned char *)reply+bytes_read)[0], + ((unsigned char *)reply+bytes_read)[1], + ((unsigned char *)reply+bytes_read)[2], + ((unsigned char *)reply+bytes_read)[3], + ((unsigned char *)reply+bytes_read)[4]); bytes_read += result; /* Once we've read 5 bytes, figure out total message length and @@ -418,7 +426,7 @@ static int _xioopen_socks5_request( } #endif - if (writefull(sfd->fd, req, bytes) < 0) { + if (writefull(sfd->fd, req, bytes, NULL) < 0) { Msg4(level, "write(%d, %p, %d): %s", sfd->fd, req, bytes, strerror(errno)); if (Close(sfd->fd) < 0) { @@ -504,6 +512,7 @@ static int xioopen_socks5( { int socks_command = addrdesc->arg1; bool dofork = false; + int maxchildren = 0; int socktype = SOCK_STREAM; int pf = PF_UNSPEC; int ipproto = IPPROTO_TCP; @@ -511,17 +520,12 @@ static int xioopen_socks5( struct opt *opts0 = NULL; struct single *sfd = &xxfd->stream; const char *socks_server, *target_name, *target_port, *socks_port; - union sockaddr_union us_sa, *us = &us_sa; - socklen_t uslen = sizeof(us_sa); - struct addrinfo **themarr, *themp; + struct addrinfo **bindarr = NULL; + struct addrinfo **themarr = NULL; + uint16_t bindport = 0; bool needbind = false; bool lowport = false; - char infobuff[256]; - if (!xioparms.experimental) { - Error1("%s: use option --experimental to acknowledge unmature state", argv[0]); - return STAT_NORETRY; - } if (argc < 4 || argc > 5) { xio_syntax(argv[0], 4, argc-1, addrdesc->syntax); return STAT_NORETRY; @@ -533,78 +537,120 @@ static int xioopen_socks5( target_name = argv[3]; target_port = argv[4]; } else { + socks_port = NULL; target_name = argv[2]; target_port = argv[3]; } - if (sfd->howtoend == END_UNSPEC) - sfd->howtoend = END_SHUTDOWN; - if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1; - applyopts(sfd, -1, opts, PH_INIT); - - retropt_int(opts, OPT_SO_TYPE, &socktype); - retropt_bool(opts, OPT_FORK, &dofork); + /* Apply and retrieve some options */ + result = _xioopen_ipapp_init(sfd, xioflags, opts, + &dofork, &maxchildren, + &pf, &socktype, &ipproto); + if (result != STAT_OK) + return result; if (_xioopen_opt_socksport(opts, (char **)&socks_port) < 0) { return STAT_NORETRY; } + /*! possible memory leak */ - result = _xioopen_ipapp_prepare(opts, &opts0, socks_server, socks_port, - &pf, ipproto, - sfd->para.socket.ip.ai_flags, - &themarr, us, &uslen, - &needbind, &lowport, socktype); + opts0 = opts; + opts = NULL; - Notice2("connecting to socks5 server %s:%s", - socks_server, socks_port); + Notice4("opening connection to %s:%s vis socks5 server %s:%s", + target_name, target_port, socks_server, socks_port); - do { + do { /* loop over retries (failed connect and socks-request attempts) + and/or forks */ + int _errno; #if WITH_RETRY if (sfd->forever || sfd->retry) { - level = E_INFO; - } else { - level = E_ERROR; - } + level = E_NOTICE; + } else #endif + level = E_WARN; - /* loop over themarr */ - themp = themarr[0]; - while (themp != NULL) { - Notice1("opening connection to %s", - sockaddr_info(themp->ai_addr, themp->ai_addrlen, - infobuff, sizeof(infobuff))); - result = _xioopen_connect(sfd, needbind?us:NULL, sizeof(*us), - themp->ai_addr, themp->ai_addrlen, - opts, pf?pf:themp->ai_family, socktype, - IPPROTO_TCP, lowport, level); - if (result == STAT_OK) - break; - themp = themp->ai_next; - if (themp == NULL) - result = STAT_RETRYLATER; + opts = copyopts(opts0, GROUP_ALL); - switch(result){ - break; + result = + _xioopen_ipapp_prepare(&opts, opts0, socks_server, socks_port, + pf, socktype, ipproto, + sfd->para.socket.ip.ai_flags, + &themarr, &bindarr, &bindport, &needbind, + &lowport); + switch (result) { + case STAT_OK: break; #if WITH_RETRY - case STAT_RETRYLATER: - case STAT_RETRYNOW: - if (sfd->forever || sfd->retry-- ) { - if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL); - continue; - } -#endif - default: + case STAT_RETRYLATER: + case STAT_RETRYNOW: + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) + Nanosleep(&sfd->intervall, NULL); + if (bindarr != NULL) xiofreeaddrinfo(bindarr); xiofreeaddrinfo(themarr); - return result; + freeopts(opts); + continue; } - } - xiofreeaddrinfo(themarr); - applyopts(sfd, -1, opts, PH_ALL); - - if ((result = _xio_openlate(sfd, opts)) < 0) +#endif /* WITH_RETRY */ + /* FALLTHROUGH */ + case STAT_NORETRY: + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + freeopts(opts); + freeopts(opts0); return result; + } - if ((result = _xioopen_socks5_handshake(sfd, level)) != STAT_OK) { + Notice2("opening connection to socks5 server %s:%s", + socks_server, socks_port); + result = + _xioopen_ipapp_connect(sfd, socks_server, opts, themarr, + needbind, bindarr, bindport, lowport, level); + _errno = errno; + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + switch (result) { + case STAT_OK: break; +#if WITH_RETRY + case STAT_RETRYLATER: + case STAT_RETRYNOW: + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) { + Nanosleep(&sfd->intervall, NULL); + } + freeopts(opts); + continue; + } +#endif /* WITH_RETRY */ + /* FALLTHROUGH */ + default: + Error4("%s:%s:%s:...: %s", + argv[0], socks_server, socks_port, + _errno?strerror(_errno):"(See above)"); + freeopts(opts0); + freeopts(opts); + return result; + } + + result = _xioopen_socks5_handshake(sfd, level); + switch (result) { + case STAT_OK: break; +#if WITH_RETRY + case STAT_RETRYLATER: + case STAT_RETRYNOW: + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) { + Nanosleep(&sfd->intervall, NULL); + } + freeopts(opts); + continue; + } +#endif /* WITH_RETRY */ + /* FALLTHROUGH */ + default: + Error3("%s:%s:%s: Connection failed", argv[0], socks_server, socks_port); + freeopts(opts0); + freeopts(opts); return result; } @@ -616,11 +662,16 @@ static int xioopen_socks5( case STAT_RETRYLATER: case STAT_RETRYNOW: if ( sfd->forever || sfd->retry-- ) { - if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL); + if (result == STAT_RETRYLATER) + Nanosleep(&sfd->intervall, NULL); + freeopts(opts); continue; } -#endif +#endif /* WITH_RETRY */ + /* FALLTHROUGH */ default: + freeopts(opts); + freeopts(opts0); return result; } @@ -636,12 +687,18 @@ static int xioopen_socks5( level = E_WARN; } while ((pid = xio_fork(false, level, sfd->shutup)) < 0) { - if (sfd->forever || --sfd->retry) { + if (sfd->forever || sfd->retry) { + if (sfd->retry > 0) + --sfd->retry; Nanosleep(&sfd->intervall, NULL); + freeopts(opts); continue; } + freeopts(opts); + freeopts(opts0); return STAT_RETRYLATER; } + if ( pid == 0 ) { sfd->forever = false; sfd->retry = 0; @@ -650,17 +707,26 @@ static int xioopen_socks5( Close(sfd->fd); Nanosleep(&sfd->intervall, NULL); - dropopts(opts, PH_ALL); - opts = copyopts(opts0, GROUP_ALL); + while (maxchildren > 0 && num_child >= maxchildren) { + Info1("all %d allowed children are active, waiting", maxchildren); + Nanosleep(&sfd->intervall, NULL); + } + freeopts(opts); continue; } else -#endif +#endif /* WITH_RETRY */ { break; } } while (true); - return 0; + Notice4("successfully connected to %s:%s via socks5 server %s:%s", + target_name, target_port, socks_server, socks_port); + + result = _xio_openlate(sfd, opts); + freeopts(opts); + freeopts(opts0); + return STAT_OK; } #endif /* WITH_SOCKS5 */ diff --git a/xio-stdio.c b/xio-stdio.c index 9f8aac9..a84c61e 100644 --- a/xio-stdio.c +++ b/xio-stdio.c @@ -17,7 +17,7 @@ static int xioopen_stdio(int argc, const char *argv[], struct opt *opts, int xio static int xioopen_stdfd(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); -/* we specify all option groups that we can imagine for a FD, becasue the +/* We specify all option groups that we can imagine for a FD, because the changed parsing mechanism does not allow us to check the type of FD before applying the options */ const struct addrdesc xioaddr_stdio = { "STDIO", 3, xioopen_stdio, GROUP_FD|GROUP_FIFO|GROUP_CHR|GROUP_BLK|GROUP_FILE|GROUP_SOCKET|GROUP_TERMIOS|GROUP_SOCK_UNIX|GROUP_SOCK_IP|GROUP_IPAPP, 0, 0, 0 HELP(NULL) }; diff --git a/xio-streams.c b/xio-streams.c index e470f3e..3be956e 100644 --- a/xio-streams.c +++ b/xio-streams.c @@ -65,7 +65,7 @@ void dummy(void) { #else /* !defined(ENABLE_APPLYOPT) */ #include "xiosysincludes.h" -#if WITH_STREAMS /* make this address configure dependend */ +#if WITH_STREAMS /* make this address configure dependent */ #include "xioopen.h" #include "xio-fd.h" diff --git a/xio-tcpwrap.c b/xio-tcpwrap.c index 26a3a1f..b8d2797 100644 --- a/xio-tcpwrap.c +++ b/xio-tcpwrap.c @@ -79,7 +79,7 @@ int xio_retropt_tcpwrap( } -/* returns -1 if forbidden, 0 if no tcpwrap check, or 1 if explicitely allowed +/* Returns -1 if forbidden, 0 if no tcpwrap check, or 1 if explicitly allowed */ int xio_tcpwrap_check( struct single *sfd, diff --git a/xio-termios.c b/xio-termios.c index 60209f7..976165d 100644 --- a/xio-termios.c +++ b/xio-termios.c @@ -501,7 +501,7 @@ int xiotermios_spec(int fd, int optcode) { #if HAVE_CFMAKERAW cfmakeraw(&_xiotermios_data.termarg); #else - /* these setting follow the Linux documenation of cfmakeraw */ + /* These settings follow the Linux documentation of cfmakeraw */ _xiotermios_data.termarg.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); _xiotermios_data.termarg.c_oflag &= ~(OPOST); diff --git a/xio-tun.c b/xio-tun.c index f66be7e..4618da4 100644 --- a/xio-tun.c +++ b/xio-tun.c @@ -120,7 +120,7 @@ static int xioopen_tun( if (retropt_bool(opts, OPT_IFF_NO_PI, &no_pi) == 0) { if (no_pi) { ifr.ifr_flags |= IFF_NO_PI; -#if 0 /* not neccessary for now */ +#if 0 /* not necessary for now */ } else { ifr.ifr_flags &= ~IFF_NO_PI; #endif @@ -139,7 +139,7 @@ static int xioopen_tun( /* we seem to need a socket for manipulating the interface */ if ((sockfd = Socket(PF_INET, SOCK_DGRAM, 0)) < 0) { Error1("socket(PF_INET, SOCK_DGRAM, 0): %s", strerror(errno)); - sockfd = sfd->fd; /* desparate fallback attempt */ + sockfd = sfd->fd; /* desperate fallback attempt */ } /*--------------------- setting interface address and netmask ------------*/ diff --git a/xio-udp.c b/xio-udp.c index 10704e3..94a8947 100644 --- a/xio-udp.c +++ b/xio-udp.c @@ -85,7 +85,7 @@ int _xioopen_ipdgram_listen(struct single *sfd, return STAT_NORETRY; } -#if WITH_IP4 /*|| WITH_IP6*/ +#if WITH_IP4 || WITH_IP6 if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, pf, &sfd->para.socket.range, sfd->para.socket.ip.ai_flags) @@ -277,8 +277,10 @@ int xioopen_ipdgram_listen( int pf = addrdesc->arg1; int ipproto = addrdesc->arg2; union sockaddr_union us; + int bind_rc; int socktype = SOCK_DGRAM; socklen_t uslen; + int result; if (argc != 2) { xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); @@ -295,12 +297,31 @@ int xioopen_ipdgram_listen( applyopts(sfd, -1, opts, PH_INIT); uslen = socket_init(pf, &us); - retropt_bind(opts, pf, socktype, ipproto, + bind_rc = retropt_bind(opts, pf, socktype, ipproto, (struct sockaddr *)&us, &uslen, 1, xfd->stream.para.socket.ip.ai_flags); + if (bind_rc == STAT_NORETRY) + return STAT_NORETRY; + if (pf == PF_UNSPEC && bind_rc == STAT_OK) + pf = us.soa.sa_family; if (false) { ; +#if WITH_IP4 || WITH_IP6 + } else if (pf == PF_UNSPEC && bind_rc == STAT_NOACTION) { + int ai_flags[2]; + ai_flags[0] = sfd->para.socket.ip.ai_flags[0]; + ai_flags[1] = sfd->para.socket.ip.ai_flags[1]; + if (!(ai_flags[1] & AI_PASSIVE)) + ai_flags[0] |= AI_PASSIVE; + result = + xioresolve(NULL, portname, pf, socktype, ipproto, &us, &uslen, ai_flags); + if (result != STAT_OK) { + Error("error resolving bind option"); + return STAT_NORETRY; + } + pf = us.soa.sa_family; +#endif /* WITH_IP4 || WITH_IP6*/ #if WITH_IP4 } else if (pf == PF_INET) { us.ip4.sin_port = parseport(portname, ipproto); @@ -349,7 +370,7 @@ int xioopen_udp_sendto( applies and consumes the following option: PH_INIT, PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECTED, PH_LATE OFUNC_OFFSET - OPT_BIND, OPT_SOURCEPORT, OPT_LOWPORT, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC + OPT_BIND, OPT_SOURCEPORT, OPT_LOWPORT, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_O_CLOEXEC */ int _xioopen_udp_sendto(const char *hostname, const char *servname, struct opt *opts, @@ -529,7 +550,7 @@ int xioopen_udp_recvfrom( if (sfd->howtoend == END_UNSPEC) sfd->howtoend = END_NONE; - /* Set AI_PASSIVE, except when it is explicitely disabled */ + /* Set AI_PASSIVE, except when it is explicitly disabled */ ai_flags2[0] = xfd->stream.para.socket.ip.ai_flags[0]; ai_flags2[1] = xfd->stream.para.socket.ip.ai_flags[1]; if (!(ai_flags2[1] & AI_PASSIVE)) @@ -605,7 +626,7 @@ int xioopen_udp_recv( xioinit_ip(&pf, xioparms.default_ip); retropt_socket_pf(opts, &pf); - /* Set AI_PASSIVE, except when it is explicitely disabled */ + /* Set AI_PASSIVE, except when it is explicitly disabled */ ai_flags2[0] = xfd->stream.para.socket.ip.ai_flags[0]; ai_flags2[1] = xfd->stream.para.socket.ip.ai_flags[1]; if (!(ai_flags2[1] & AI_PASSIVE)) @@ -646,7 +667,7 @@ int xioopen_udp_recv( } #endif -#if WITH_IP4 /*|| WITH_IP6*/ +#if WITH_IP4 || WITH_IP6 if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, pf, &xfd->stream.para.socket.range, xfd->stream.para.socket.ip.ai_flags) diff --git a/xio-unix.c b/xio-unix.c index 42bb2a3..735b4af 100644 --- a/xio-unix.c +++ b/xio-unix.c @@ -15,7 +15,7 @@ #if WITH_UNIX -/* to avoid unneccessary runtime if () conditionals when no abstract support is +/* To avoid unnecessary runtime if () conditionals when no abstract support is compiled in (or at least to give optimizing compilers a good chance) we need a constant that can be used in C expressions */ #if WITH_ABSTRACT_UNIXSOCKET @@ -33,7 +33,7 @@ static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, i /* the first free parameter is 0 for "normal" unix domain sockets, or 1 for abstract unix sockets (Linux); the second and third free parameter are - unsused */ + unused */ const struct addrdesc xioaddr_unix_connect = { "UNIX-CONNECT", 1+XIO_RDWR, xioopen_unix_connect, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":<filename>") }; #if WITH_LISTEN const struct addrdesc xioaddr_unix_listen = { "UNIX-LISTEN", 1+XIO_RDWR, xioopen_unix_listen, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":<filename>") }; @@ -123,6 +123,7 @@ static int xioopen_unix_listen( /* we expect the form: filename */ const char *name; xiosingle_t *sfd = &xxfd->stream; + char *bindstring = NULL; int pf = PF_UNIX; int socktype = SOCK_STREAM; int protocol = 0; @@ -140,6 +141,12 @@ static int xioopen_unix_listen( } name = argv[1]; + if (retropt_string(opts, OPT_BIND, &bindstring) == 0) { + Error2("%s:%s: binds implicitly, bind option not allowed", + addrdesc->defname, argv[1]); + free(bindstring); + } + sfd->para.socket.un.tight = UNIX_TIGHTSOCKLEN; retropt_socket_pf(opts, &pf); if (sfd->howtoend == END_UNSPEC) @@ -257,7 +264,12 @@ static int xioopen_unix_connect( if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen, (addrdesc->arg1/*abstract*/<<1)|sfd->para.socket.un.tight, - sfd->para.socket.ip.ai_flags) +#if WITH_TCP + sfd->para.socket.ip.ai_flags +#else + 0 +#endif /* WITH_TCP */ +) == STAT_OK) { needbind = true; } @@ -426,7 +438,12 @@ static int xioopen_unix_sendto( if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen, (addrdesc->arg1/*abstract*/<<1)| sfd->para.socket.un.tight, - sfd->para.socket.ip.ai_flags) +#if WITH_TCP + sfd->para.socket.ip.ai_flags +#else + 0 +#endif /* WITH_TCP */ + ) == STAT_OK) { needbind = true; } @@ -665,7 +682,7 @@ static int xioopen_unix_client( PH_CONNECTED, PH_LATE, ?PH_CONNECT OFUNC_OFFSET, OPT_PROTOCOL_FAMILY, OPT_UNIX_TIGHTSOCKLEN, OPT_UNLINK_CLOSE, OPT_BIND, - OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_CLOEXEC, OPT_USER, OPT_GROUP, ?OPT_FORK, + OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_O_CLOEXEC, OPT_USER, OPT_GROUP, ?OPT_FORK, */ int _xioopen_unix_client( @@ -709,7 +726,12 @@ _xioopen_unix_client( if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen, (abstract<<1)|sfd->para.socket.un.tight, - sfd->para.socket.ip.ai_flags) +#if WITH_TCP + sfd->para.socket.ip.ai_flags +#else + 0 +#endif /* WITH_TCP */ + ) != STAT_NOACTION) { needbind = true; } @@ -773,7 +795,7 @@ _xioopen_unix_client( opts, pf, SOCK_SEQPACKET, protocol, needtemp, E_INFO)) == 0) break; - if (errno != EPROTOTYPE && errno != EPROTONOSUPPORT/*AIX*/ + if (errno != EPROTOTYPE && errno != EPROTONOSUPPORT/*AIX*/ && errno != ESOCKTNOSUPPORT/*Debian3*/ #if WITH_ABSTRACT_UNIXSOCKET && !(abstract && errno == ECONNREFUSED) #endif diff --git a/xio-vsock.c b/xio-vsock.c index fcd09bc..0531994 100644 --- a/xio-vsock.c +++ b/xio-vsock.c @@ -98,7 +98,7 @@ static int xioopen_vsock_connect( ret = retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&sa_local, &sa_len, 3, - sfd->para.socket.ip.ai_flags); + NULL); if (ret == STAT_NORETRY) return ret; if (ret == STAT_OK) diff --git a/xio.h b/xio.h index a276a56..05bef49 100644 --- a/xio.h +++ b/xio.h @@ -120,12 +120,13 @@ typedef struct xioparms { const char *sniffleft_name; /* file name with -r */ const char *sniffright_name; /* file name with -R */ size_t bufsiz; + struct timeval total_timeout;/* when nothing happens, die after seconds */ } xioparms_t; /* pack the description of a lock file */ typedef struct { const char *lockfile; /* name of lockfile; NULL if no locking */ - bool waitlock; /* dont't exit when already locked */ + bool waitlock; /* don't exit when already locked */ struct timespec intervall; /* polling intervall */ } xiolock_t; diff --git a/xioconfig.h b/xioconfig.h index 1c12c1a..ab3d115 100644 --- a/xioconfig.h +++ b/xioconfig.h @@ -16,7 +16,13 @@ # define WITH_OPEN 1 #endif -#if WITH_OPEN || WITH_PIPE || WITH_UNIX || WITH_PTY +#if WITH_INTERFACE || WITH_TUN +# define _WITH_INTERFACE 1 +#else +# define _WITH_INTERFACE 0 +#endif + +#if WITH_OPEN || WITH_PIPE || WITH_UNIX || WITH_PTY || _WITH_INTERFACE # define WITH_NAMED 1 #endif @@ -34,7 +40,7 @@ with IP6 */ #endif -#if WITH_OPENSSL +#if WITH_OPENSSL || WITH_SOCKS5 # define WITH_TCP 1 # define WITH_IP4 1 #endif @@ -57,7 +63,7 @@ # define _WITH_UDP 1 #endif -#if WITH_UNIX || WITH_IP4 || WITH_IP6 || WITH_SOCKS4 || WITH_RAWIP || WITH_GENERICSOCKET +#if WITH_UNIX || WITH_IP4 || WITH_IP6 || WITH_SOCKS4 || WITH_SOCKS5 || WITH_RAWIP || WITH_GENERICSOCKET || WITH_SOCKETPAIR || WITH_VSOCK # define _WITH_SOCKET 1 #else # undef _WITH_SOCKET @@ -71,10 +77,8 @@ # undef WITH_LIBWRAP #endif -#if WITH_INTERFACE || WITH_TUN -# define _WITH_INTERFACE 1 -#else -# define _WITH_INTERFACE 0 +#if WITH_SOCKETPAIR || WITH_EXEC || WITH_SYSTEM || WITH_SHELL +# define _WITH_SOCKETPAIR 1 #endif #if WITH_GENERICSOCKET || _WITH_INTERFACE diff --git a/xiohelp.c b/xiohelp.c index 1ba92a8..fae8cfb 100644 --- a/xiohelp.c +++ b/xiohelp.c @@ -53,7 +53,7 @@ static const char *addressgroupnames[] = { /* keep consistent with xioopts.h:enum ephase ! */ static char *optionphasenames[] = { - "ALL", "INIT", "EARLY", + "ALL", "OFFSET", "INIT", "EARLY", "PREOPEN", "OPEN", "PASTOPEN", "PRESOCKET", "SOCKET", "PASTSOCKET", "PREBIGEN", "BIGEN", "PASTBIGEN", @@ -87,6 +87,8 @@ static int xiohelp_option(FILE *of, const struct optname *on, const char *name) groups = on->desc->group; occurred = false; chars = 7; + if (groups == 0) + fputs("(all)", of); for (j = 0; j < 8*sizeof(groups_t); ++j) { if (groups & 1) { if (occurred) { @@ -150,8 +152,9 @@ int xioopenhelp(FILE *of, i = (40 - chars + 7) / 8; for (; i > 0; --i) { fputc('\t', of); } fputs("\tgroups=", of); - groups = an->desc->groups; occurred = false; - for (j = 0; j < 32; ++j) { + groups = an->desc->groups; + occurred = false; + for (j = 0; j < sizeof(groups_t)*8; ++j) { if (groups & 1) { if (occurred) { fputc(',', of); } fprintf(of, "%s", addressgroupnames[j]); diff --git a/xioinitialize.c b/xioinitialize.c index b06915e..3abc8e2 100644 --- a/xioinitialize.c +++ b/xioinitialize.c @@ -175,8 +175,8 @@ static int xio_nokill(xiofile_t *sock) { return result; } -/* call this function immediately after fork() in child process */ -/* it performs some neccessary actions +/* Call this function immediately after fork() in child process */ +/* It performs some necessary actions returns 0 on success or != 0 if an error occurred */ int xio_forked_inchild(void) { int result = 0; diff --git a/xiolayer.c b/xiolayer.c index 83b8839..a378293 100644 --- a/xiolayer.c +++ b/xiolayer.c @@ -48,7 +48,8 @@ int xio_chdir( free(tmp_dir); return -1; } - *orig_dir = Realloc(*orig_dir, strlen(*orig_dir)+1); + /*0 *orig_dir = Realloc(*orig_dir, strlen(*orig_dir)+1); */ + *orig_dir = Realloc3(*orig_dir, strlen(*orig_dir)+1, PATH_MAX); if (Chdir(tmp_dir) < 0) { Error2("chdir(\"%s\"): %s", tmp_dir, strerror(errno)); diff --git a/xiolockfile.c b/xiolockfile.c index c6896d4..ff29c2f 100644 --- a/xiolockfile.c +++ b/xiolockfile.c @@ -52,7 +52,7 @@ int xiogetlock(const char *lockfile) { pid = Getpid(); bytes = sprintf(pidbuf, F_pid"\n", pid); - if (writefull(fd, pidbuf, bytes) < 0) { + if (writefull(fd, pidbuf, bytes, NULL) < 0) { Error4("write(%d, %p, "F_Zu"): %s", fd, pidbuf, bytes, strerror(errno)); return -1; } diff --git a/xioopen.c b/xioopen.c index be17e3b..30ec859 100644 --- a/xioopen.c +++ b/xioopen.c @@ -177,11 +177,13 @@ const struct addrname addressnames[] = { { "PIPE", &xioaddr_pipe }, #endif #if WITH_POSIXMQ + { "POSIXMQ", &xioaddr_posixmq_bidir }, { "POSIXMQ-BIDIRECTIONAL", &xioaddr_posixmq_bidir }, { "POSIXMQ-READ", &xioaddr_posixmq_read }, { "POSIXMQ-RECEIVE", &xioaddr_posixmq_receive }, { "POSIXMQ-RECV", &xioaddr_posixmq_receive }, { "POSIXMQ-SEND", &xioaddr_posixmq_send }, + { "POSIXMQ-WRITE", &xioaddr_posixmq_write }, #endif #if WITH_PROXY { "PROXY", &xioaddr_proxy_connect }, @@ -471,14 +473,14 @@ static xiofile_t *xioallocfd(void) { fd->stream.escape = -1; /* fd->stream.para.exec.pid = 0; */ fd->stream.lineterm = LINETERM_RAW; -#if WITH_RESOLVE +#if ( _WITH_IP4 || _WITH_IP6 ) && WITH_RESOLVE #if HAVE_RES_RETRANS fd->stream.para.socket.ip.res.retrans = -1; #endif #if HAVE_RES_RETRY fd->stream.para.socket.ip.res.retry = -1; #endif -#endif /* WITH_RESOLVE */ +#endif /* ( _WITH_IP4 || _WITH_IP6 ) && WITH_RESOLVE */ return fd; } @@ -701,10 +703,10 @@ int xioopen_single(xiofile_t *xfd, int xioflags) { mode_t orig_umask, tmp_umask; int result; /* Values to be saved until xioopen() is finished */ -#if WITH_RESOLVE && HAVE_RESOLV_H +#if ( _WITH_IP4 || _WITH_IP6 ) && WITH_RESOLVE && HAVE_RESOLV_H int do_res; struct __res_state save_res; -#endif /* WITH_RESOLVE && HAVE_RESOLV_H */ +#endif #if WITH_NAMESPACES int save_netfd = -1; #endif @@ -730,15 +732,15 @@ int xioopen_single(xiofile_t *xfd, int xioflags) { if (applyopts_single(sfd, sfd->opts, PH_OFFSET) < 0) return -1; -#if WITH_NAMESPACES +#if WITH_NAMESPACES /* netns */ if ((save_netfd = xio_apply_namespace(sfd->opts)) < 0) return -1; #endif /* WITH_NAMESPACES */ -#if WITH_RESOLVE && HAVE_RESOLV_H +#if ( _WITH_IP4 || _WITH_IP6 ) && WITH_RESOLVE && HAVE_RESOLV_H if ((do_res = xio_res_init(sfd, &save_res)) < 0) return STAT_NORETRY; -#endif /* WITH_RESOLVE && HAVE_RESOLV_H */ +#endif if (xio_chdir(sfd->opts, &orig_dir) < 0) return STAT_NORETRY; @@ -769,10 +771,10 @@ int xioopen_single(xiofile_t *xfd, int xioflags) { free(orig_dir); } -#if WITH_RESOLVE && HAVE_RESOLV_H +#if ( _WITH_IP4 || _WITH_IP6 ) && WITH_RESOLVE && HAVE_RESOLV_H if (do_res) xio_res_restore(&save_res); -#endif /* WITH_RESOLVE && HAVE_RESOLV_H */ +#endif #if WITH_NAMESPACES if (save_netfd > 0) { diff --git a/xioopts.c b/xioopts.c index a751fd3..901a82b 100644 --- a/xioopts.c +++ b/xioopts.c @@ -177,7 +177,7 @@ static int applyopt(struct single *sfd, int fd, struct opt *opt); binary search! */ /* NULL terminated */ const struct optname optionnames[] = { -#if HAVE_RESOLV_H && WITH_RES_AAONLY +#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H && WITH_RES_AAONLY IF_RESOLVE("aaonly", &opt_res_aaonly) #endif #ifdef TCP_ABORT_THRESHOLD /* HP_UX */ @@ -352,7 +352,7 @@ const struct optname optionnames[] = { #endif /* SO_CKSUMRECV */ /*IF_NAMED ("cleanup", &opt_cleanup)*/ IF_TERMIOS("clocal", &opt_clocal) - IF_ANY ("cloexec", &opt_cloexec) + IF_ANY ("cloexec", &opt_cloexec) IF_ANY ("close", &opt_end_close) IF_OPENSSL("cn", &opt_openssl_commonname) IF_OPENSSL("commonname", &opt_openssl_commonname) @@ -390,8 +390,8 @@ const struct optname optionnames[] = { # endif #endif /* defined(CRDLY) */ IF_TERMIOS("cread", &opt_cread) - IF_OPEN ("creat", &opt_o_create) - IF_OPEN ("create", &opt_o_create) + IF_OPEN ("creat", &opt_o_creat) + IF_OPEN ("create", &opt_o_creat) IF_ANY ("crlf", &opt_crnl) IF_ANY ("crnl", &opt_crnl) IF_TERMIOS("crterase", &opt_echoe) @@ -421,7 +421,7 @@ const struct optname optionnames[] = { #ifdef TCP_DEFER_ACCEPT /* Linux 2.4.0 */ IF_TCP ("defer-accept", &opt_tcp_defer_accept) #endif -#if HAVE_RESOLV_H +#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H IF_RESOLVE("defnames", &opt_res_defnames) #endif /* HAVE_RESOLV_H */ #ifdef O_DELAY @@ -454,10 +454,10 @@ const struct optname optionnames[] = { #ifdef VDISCARD IF_TERMIOS("discard", &opt_vdiscard) #endif -#if WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST +#if (WITH_IP4 || WITH_IP6) && WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST IF_IP ("dns", &opt_res_nsaddr) #endif -#if HAVE_RESOLV_H +#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H IF_RESOLVE("dnsrch", &opt_res_dnsrch) #endif /* HAVE_RESOLV_H */ #ifdef SO_DONTLINGER @@ -721,7 +721,7 @@ const struct optname optionnames[] = { IF_ANY ("ignoreeof", &opt_ignoreeof) IF_ANY ("ignoreof", &opt_ignoreeof) IF_TERMIOS("ignpar", &opt_ignpar) -#if HAVE_RESOLV_H +#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H IF_RESOLVE("igntc", &opt_res_igntc) #endif /* HAVE_RESOLV_H */ IF_TERMIOS("imaxbel", &opt_imaxbel) @@ -1032,7 +1032,10 @@ const struct optname optionnames[] = { #endif IF_ANY ("mode", &opt_perm) #if WITH_POSIXMQ - IF_ANY ("mq-prio", &opt_posixmq_priority) + IF_ANY ("mq-flush", &opt_posixmq_flush) + IF_ANY ("mq-maxmsg", &opt_posixmq_maxmsg) + IF_ANY ("mq-msgsize", &opt_posixmq_msgsize) + IF_ANY ("mq-prio", &opt_posixmq_priority) #endif #ifdef TCP_MAXSEG IF_TCP ("mss", &opt_tcp_maxseg) @@ -1050,7 +1053,7 @@ const struct optname optionnames[] = { IF_IP ("multicast-ttl", &opt_ip_multicast_ttl) IF_IP ("multicastloop", &opt_ip_multicast_loop) IF_IP ("multicastttl", &opt_ip_multicast_ttl) -#if WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST +#if (WITH_IP4 || WITH_IP6) && WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST IF_IP ("nameserver", &opt_res_nsaddr) #endif #if defined(O_NDELAY) && (!defined(O_NONBLOCK) || O_NDELAY != O_NONBLOCK) @@ -1118,7 +1121,7 @@ const struct optname optionnames[] = { IF_OPENSSL("nosni", &opt_openssl_no_sni) #endif IF_INTERFACE("notrailers", &opt_iff_notrailers) -#if WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST +#if (WITH_IP4 || WITH_IP6) && WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST IF_IP ("nsaddr", &opt_res_nsaddr) #endif #ifdef O_NSHARE @@ -1132,8 +1135,8 @@ const struct optname optionnames[] = { #ifdef O_BINARY IF_OPEN ("o-binary", &opt_o_binary) #endif - IF_OPEN ("o-creat", &opt_o_create) - IF_OPEN ("o-create", &opt_o_create) + IF_OPEN ("o-creat", &opt_o_creat) + IF_OPEN ("o-create", &opt_o_creat) #ifdef O_DEFER IF_OPEN ("o-defer", &opt_o_defer) #endif @@ -1191,7 +1194,8 @@ const struct optname optionnames[] = { #endif IF_OPEN ("o-trunc", &opt_o_trunc) IF_OPEN ("o-wronly", &opt_o_wronly) - IF_OPEN ("o_create", &opt_o_create) + IF_OPEN ("o_creat", &opt_o_creat) + IF_OPEN ("o_create", &opt_o_creat) #ifdef O_DEFER IF_OPEN ("o_defer", &opt_o_defer) #endif @@ -1348,9 +1352,12 @@ const struct optname optionnames[] = { IF_INTERFACE("portsel", &opt_iff_portsel) #endif #if WITH_POSIXMQ + IF_ANY ("posixmq-flush", &opt_posixmq_flush) + IF_ANY ("posixmq-maxmsg", &opt_posixmq_maxmsg) + IF_ANY ("posixmq-msgsize", &opt_posixmq_msgsize) IF_ANY ("posixmq-priority", &opt_posixmq_priority) #endif -#if HAVE_RESOLV_H && WITH_RES_PRIMARY +#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H && WITH_RES_PRIMARY IF_RESOLVE("primary", &opt_res_primary) #endif #ifdef SO_PRIORITY @@ -1411,7 +1418,7 @@ const struct optname optionnames[] = { IF_OPEN ("rdonly", &opt_o_rdonly) IF_OPEN ("rdwr", &opt_o_rdwr) IF_ANY ("readbytes", &opt_readbytes) -#if HAVE_RESOLV_H +#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H IF_RESOLVE("recurse", &opt_res_recurse) #endif /* HAVE_RESOLV_H */ #ifdef IP_RECVDSTADDR @@ -1451,7 +1458,7 @@ const struct optname optionnames[] = { #ifdef VREPRINT IF_TERMIOS("reprint", &opt_vreprint) #endif -#if HAVE_RESOLV_H +#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H # if WITH_AA_ONLY IF_RESOLVE("res-aaonly", &opt_res_aaonly) # endif @@ -1480,15 +1487,15 @@ const struct optname optionnames[] = { # endif IF_RESOLVE("res-stayopen", &opt_res_stayopen) IF_RESOLVE("res-usevc", &opt_res_usevc) -#endif /* HAVE_RESOLV_H */ +#endif /* (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H */ IF_PROXY ("resolv", &opt_proxy_resolve) IF_PROXY ("resolve", &opt_proxy_resolve) #ifdef IP_RETOPTS IF_IP ("retopts", &opt_ip_retopts) #endif -# if HAVE_RES_RETRANS +#if (WITH_IP4 || WITH_IP6) && HAVE_RES_RETRANS IF_RESOLVE("retrans", &opt_res_retrans) -# endif +#endif #if WITH_INTERFACE && defined(PACKET_AUXDATA) IF_SOCKET ("retrieve-vlan", &opt_retrieve_vlan) #endif @@ -1576,8 +1583,10 @@ const struct optname optionnames[] = { #endif IF_SOCKET ("setsockopt", &opt_setsockopt) IF_SOCKET ("setsockopt-bin", &opt_setsockopt_bin) + IF_SOCKET ("setsockopt-connected", &opt_setsockopt_connected) IF_SOCKET ("setsockopt-int", &opt_setsockopt_int) IF_SOCKET ("setsockopt-listen", &opt_setsockopt_listen) + IF_SOCKET ("setsockopt-socket", &opt_setsockopt_socket) IF_SOCKET ("setsockopt-string", &opt_setsockopt_string) IF_ANY ("setuid", &opt_setuid) IF_ANY ("setuid-early", &opt_setuid_early) @@ -1712,8 +1721,10 @@ const struct optname optionnames[] = { #endif /* SO_USELOOPBACK */ IF_SOCKET ("sockopt", &opt_setsockopt) IF_SOCKET ("sockopt-bin", &opt_setsockopt_bin) + IF_SOCKET ("sockopt-conn", &opt_setsockopt_connected) IF_SOCKET ("sockopt-int", &opt_setsockopt_int) IF_SOCKET ("sockopt-listen", &opt_setsockopt_listen) + IF_SOCKET ("sockopt-sock", &opt_setsockopt_socket) IF_SOCKET ("sockopt-string", &opt_setsockopt_string) IF_SOCKS4 ("socksport", &opt_socksport) IF_SOCKS4 ("socksuser", &opt_socksuser) @@ -1724,7 +1735,7 @@ const struct optname optionnames[] = { IF_IPAPP ("sourceport", &opt_sourceport) IF_IPAPP ("sp", &opt_sourceport) IF_TERMIOS("start", &opt_vstart) -#if HAVE_RESOLV_H +#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H IF_RESOLVE("stayopen", &opt_res_stayopen) #endif /* HAVE_RESOLV_H */ IF_EXEC ("stderr", &opt_stderr) @@ -1930,7 +1941,7 @@ const struct optname optionnames[] = { IF_ANY ("user", &opt_user) IF_NAMED ("user-early", &opt_user_early) IF_ANY ("user-late", &opt_user_late) -#if HAVE_RESOLV_H +#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H IF_RESOLVE("usevc", &opt_res_usevc) #endif /* HAVE_RESOLV_H */ #if defined(AI_V4MAPPED) @@ -2654,13 +2665,13 @@ int parseopts_table(const char **a, groups_t groups, struct opt **opts, (*opts)[i].value3.u_string); break; -#if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) +#if (WITH_IP4 || WITH_IP6) && ( defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) ) case TYPE_IP_MREQN: xiotype_ip_add_membership(token, ent, opt); break; -#endif /* defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) */ +#endif /* WITH_IP && defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) ) */ -#if defined(HAVE_STRUCT_IP_MREQ_SOURCE) && defined(IP_ADD_SOURCE_MEMBERSHIP) +#if _WITH_IP4 && defined(HAVE_STRUCT_IP_MREQ_SOURCE) case TYPE_IP_MREQ_SOURCE: xiotype_ip_add_source_membership(token, ent, opt); break; @@ -2768,7 +2779,8 @@ int parseopts_table(const char **a, groups_t groups, struct opt **opts, ++i; if ((i % 8) == 0) { - *opts = Realloc(*opts, (i+8) * sizeof(struct opt)); + /*0 *opts = Realloc(*opts, (i+8) * sizeof(struct opt)); */ + *opts = Realloc3(*opts, (i+8) * sizeof(struct opt), i * sizeof(struct opt)); if (*opts == NULL) { return -1; } @@ -2904,7 +2916,6 @@ int showleft(const struct opt *opts) { return 0; } - /* determines the address group from mode_t */ /* does not set GROUP_FD; cannot determine GROUP_TERMIOS ! */ groups_t _groupbits(mode_t mode) { @@ -3100,7 +3111,7 @@ int retropt_int(struct opt *opts, int optcode, int *result) { /* Looks for the first option of type <optcode>. If the option is found, this function stores its int value in *result, "consumes" the option, and returns 0. - If the option is not found, *result is not modified, and -1 is returned. */ + If the option is not found, values are not modified, and -1 is returned. */ int retropt_2integrals(struct opt *opts, int optcode, union integral *value1, union integral *value2) { @@ -3250,7 +3261,8 @@ int retropt_bind(struct opt *opts, int ipproto, struct sockaddr *sa, socklen_t *salen, - int feats, /* TCP etc: 1..address allowed, + int feats, /* -1..generic addr spec + TCP etc: 1..address allowed, 3..address and port allowed UNIX (or'd): 1..tight 2..abstract @@ -3274,10 +3286,13 @@ int retropt_bind(struct opt *opts, } bindp = bindname; - switch (af) { +#if WITH_IP4 && WITH_IP6 + /* Try to derive address family from string */ + if (af == AF_UNSPEC && bindname[0] == '[') + af = AF_INET6; +#endif /* WITH_IP4 && WITH_IP6 */ - case AF_UNSPEC: - { + if (feats == -1) { size_t p = 0; dalan(bindname, (uint8_t *)sa->sa_data, &p, *salen-sizeof(sa->sa_family), 'i'); *salen = p + sizeof(sa->sa_family); @@ -3289,10 +3304,13 @@ int retropt_bind(struct opt *opts, #if HAVE_STRUCT_SOCKADDR_SALEN sa->sa_len = *salen; #endif - } - break; + return STAT_OK; + } + + switch (af) { #if WITH_IP4 || WITH_IP6 || WITH_VSOCK + case AF_UNSPEC: #if WITH_VSOCK case AF_VSOCK: #endif @@ -3323,11 +3341,12 @@ int retropt_bind(struct opt *opts, } } - /* Set AI_PASSIVE, except when it is explicitely disabled */ +# if WITH_IP4 || WITH_IP6 + /* Set AI_PASSIVE, except when it is explicitly disabled */ ai_flags2[0] = ai_flags[0]; ai_flags2[1] = ai_flags[1]; if (!(ai_flags2[1] & AI_PASSIVE)) - ai_flags2[0] |= AI_PASSIVE; + ai_flags2[0] |= AI_PASSIVE; if ((result = xioresolve(hostname[0]!='\0'?hostname:NULL, portp, @@ -3337,6 +3356,8 @@ int retropt_bind(struct opt *opts, Error("error resolving bind option"); return STAT_NORETRY; } +/*# else */ +# endif /* WITH_IP4 || WITH_IP6 */ break; #endif /* WITH_IP4 || WITH_IP6 || WITH_VSOCK */ @@ -3567,6 +3588,8 @@ int applyopt_ioctl_generic( return 0; } +#if _WITH_SOCKET + int applyopt_sockopt( int fd, struct opt *opt) @@ -3695,7 +3718,7 @@ int applyopt_sockopt( } break; #endif /* HAVE_STRUCT_LINGER */ -#if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) +#if (WITH_IP4 || WITH_IP6) && ( defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) ) case TYPE_IP_MREQN: /* handled in applyopts_single */ break; @@ -3815,6 +3838,9 @@ int applyopt_sockopt_generic( return 0; } +#endif /* _WITH_SOCKET */ + +#if HAVE_FLOCK int applyopt_flock( int fd, struct opt *opt) @@ -3826,6 +3852,7 @@ int applyopt_flock( } return 0; } +#endif /* defined(HAVE_FLOCK) */ /* Applies an option that needs handling specific to its OPT_* setting. Does not overwrite the option instance with ODESC_DONE or ODESC_ERROR, @@ -3921,8 +3948,12 @@ int applyopt_spec( { struct passwd *pwd; if ((pwd = getpwuid(opt->value.u_uidt)) == NULL) { - Error1("getpwuid("F_uid"): no such user", - opt->value.u_uidt); + if (errno != 0) + Error2("getpwuid("F_uid"): %s", + opt->value.u_uidt, strerror(errno)); + else + Error1("getpwuid("F_uid"): no such user", + opt->value.u_uidt); return -1; } if (Initgroups(pwd->pw_name, pwd->pw_gid) < 0) { @@ -4216,7 +4247,7 @@ int applyopts_cloexec(int fd, struct opt *opts) { if (!opts) return 0; - retropt_bool(opts, OPT_CLOEXEC, &docloexec); + retropt_bool(opts, OPT_O_CLOEXEC, &docloexec); if (docloexec) { if (Fcntl_l(fd, F_SETFD, FD_CLOEXEC) < 0) { Warn2("fcntl(%d, F_SETFD, FD_CLOEXEC): %s", fd, strerror(errno)); @@ -4272,6 +4303,7 @@ static int applyopt_offset(struct single *sfd, struct opt *opt) { case TYPE_CONST: *(int *)ptr = opt->desc->minor; break; +#if WITH_IP4 case TYPE_IP4NAME: memset(ptr, 0, sizeof(struct sockaddr_in)); ((struct sockaddr_in *)ptr)->sin_addr = opt->value.u_ip4addr; @@ -4281,6 +4313,7 @@ static int applyopt_offset(struct single *sfd, struct opt *opt) { memset(ptr, 0, sizeof(struct sockaddr_in)); *(struct sockaddr_in *)ptr = opt->value.u_ip4sock; break; +#endif /* WITH_IP4 */ default: Error2("applyopt_offset(opt:%s): type %s not implemented", opt->desc->defname, xiohelp_opttypename(opt->desc->type)); @@ -4664,3 +4697,11 @@ int dumpopts(struct opt *opts) } return 0; } + +/* Better with type specific free function */ +void freeopts( + struct opt *opts) +{ + free(opts); + return; +} diff --git a/xioopts.h b/xioopts.h index ef3b31c..1f32161 100644 --- a/xioopts.h +++ b/xioopts.h @@ -72,7 +72,7 @@ enum e_types { #if HAVE_STRUCT_LINGER TYPE_LINGER, /* struct linger */ #endif /* HAVE_STRUCT_LINGER */ -#if HAVE_STRUCT_IP_MREQ || HAVE_STRUCT_IP_MREQN +#if (WITH_IP4 || WITH_IP6) && ( defined(HAVE_STRUCT_IP_MREQ) || defined(HAVE_STRUCT_IP_MREQN) ) TYPE_IP_MREQN, /* for struct ip_mreq or struct ip_mreqn */ #endif #if HAVE_STRUCT_IP_MREQ_SOURCE @@ -150,7 +150,7 @@ enum e_func { #define GROUP_NONE 0x00000000 #define GROUP_ADDR 0x00000000 /* options that apply to all addresses */ -#define GROUP_FD 0x00000001 /* everything applyable to a fd */ +#define GROUP_FD 0x00000001 /* everything applicable to a fd */ #define GROUP_FIFO 0x00000002 #define GROUP_CHR 0x00000004 /* not yet used? */ #define GROUP_BLK 0x00000008 @@ -272,7 +272,6 @@ enum e_optcode { OPT_CHROOT_EARLY, /* chroot() before file system access */ /*OPT_CIBAUD,*/ /* termios.c_cflag */ OPT_CLOCAL, /* termios.c_cflag */ - OPT_CLOEXEC, OPT_CONNECT_TIMEOUT, /* socket connect */ OPT_COOL_WRITE, OPT_CR, /* customized */ @@ -482,6 +481,9 @@ enum e_optcode { OPT_LOWPORT, OPT_MAX_CHILDREN, #if WITH_POSIXMQ + OPT_POSIXMQ_FLUSH, + OPT_POSIXMQ_MAXMSG, + OPT_POSIXMQ_MSGSIZE, OPT_POSIXMQ_PRIORITY, #endif #ifdef NLDLY @@ -552,7 +554,8 @@ enum e_optcode { OPT_O_ASYNC, #endif OPT_O_BINARY, /* Cygwin */ - OPT_O_CREATE, + OPT_O_CLOEXEC, + OPT_O_CREAT, #ifdef O_DEFER OPT_O_DEFER, #endif @@ -660,8 +663,10 @@ enum e_optcode { OPT_SETPGID, OPT_SETSID, OPT_SETSOCKOPT_BIN, + OPT_SETSOCKOPT_CONNECTED, OPT_SETSOCKOPT_INT, OPT_SETSOCKOPT_LISTEN, + OPT_SETSOCKOPT_SOCKET, OPT_SETSOCKOPT_STRING, OPT_SETUID, OPT_SETUID_EARLY, @@ -1028,6 +1033,7 @@ extern groups_t _groupbits(mode_t mode); extern int dropopts(struct opt *opts, unsigned int phase); extern int dropopts2(struct opt *opts, unsigned int from, unsigned int to); extern int dumpopts(struct opt *opts); +extern void freeopts(struct opt *opts); #if HAVE_BASIC_UID_T==1 # define retropt_uid(o,c,r) retropt_short(o,c,r) diff --git a/xioshutdown.c b/xioshutdown.c index c1ec796..6af190e 100644 --- a/xioshutdown.c +++ b/xioshutdown.c @@ -10,6 +10,7 @@ #include "xio-openssl.h" + static pid_t socat_kill_pid; /* here we pass the pid to be killed in sighandler */ static void signal_kill_pid(int dummy) { @@ -51,6 +52,7 @@ int xioshutdown(xiofile_t *sock, int how) { sock->stream.fd, strerror(errno)); } return 0; +#if _WITH_SOCKET case XIOSHUT_DOWN: result = Shutdown(sock->stream.fd, how); if (result < 0) { @@ -70,7 +72,6 @@ int xioshutdown(xiofile_t *sock, int how) { return -1; } return 0; -#if _WITH_SOCKET case XIOSHUT_NULL: writenull = '\0'; /* assign something to make gcc happy */ /* send an empty packet; only useful on datagram sockets? */ diff --git a/xiowrite.c b/xiowrite.c index 5388baf..c5885ad 100644 --- a/xiowrite.c +++ b/xiowrite.c @@ -50,7 +50,7 @@ ssize_t xiowrite(xiofile_t *file, const void *buff, size_t bytes) { switch (pipe->dtype & XIODATA_WRITEMASK) { case XIOWRITE_STREAM: - writt = writefull(pipe->fd, buff, bytes); + writt = writefull(pipe->fd, buff, bytes, NULL); if (writt < 0) { _errno = errno; switch (_errno) { @@ -116,8 +116,10 @@ ssize_t xiowrite(xiofile_t *file, const void *buff, size_t bytes) { case XIOWRITE_PIPE: if (pipe->para.bipipe.socktype == SOCK_STREAM) { writt = Write(pipe->para.bipipe.fdout, buff, bytes); +#if _WITH_SOCKET } else { writt = Send(pipe->para.bipipe.fdout, buff, bytes, 0); +#endif /* _WITH_SOCKET */ } _errno = errno; if (writt < 0) {