Dual type addresses terminated when they were idle for EOF timeout time

This commit is contained in:
Gerhard Rieger 2014-07-13 17:03:25 +02:00
parent 7ad17dcd90
commit 6361eec4e9
5 changed files with 65 additions and 22 deletions

View file

@ -247,6 +247,8 @@ corrections:
Fixed Debug arguments issue in _socat() Fixed Debug arguments issue in _socat()
Dual type addresses terminated when they were idle for EOF timeout time
porting: porting:
Red Hat issue 1020203: configure checks fail with some compilers. Red Hat issue 1020203: configure checks fail with some compilers.
Use case: clang Use case: clang

View file

@ -22,8 +22,8 @@ srcdir = @srcdir@
VPATH = @srcdir@ VPATH = @srcdir@
CC = @CC@ CC = @CC@
CCOPTS = $(CCOPT) -Wall -Wno-parentheses #CCOPTS = $(CCOPT) -Wall -Wno-parentheses
CCOPTS = $(CCOPT) CCOPTS = $(CCOPT) -pthread
SYSDEFS = @SYSDEFS@ SYSDEFS = @SYSDEFS@
CPPFLAGS = -I. @CPPFLAGS@ CPPFLAGS = -I. @CPPFLAGS@

View file

@ -314,7 +314,7 @@ void msg2(
bytes = sprintf(bufp, "%s ", diagopts.hostname), bufp+=bytes; bytes = sprintf(bufp, "%s ", diagopts.hostname), bufp+=bytes;
} }
bytes = sprintf(bufp, "%s["F_pid".%lu] ", bytes = sprintf(bufp, "%s["F_pid".%lu] ",
diagopts.progname, getpid(), (unsigned long)pthread_self()); diagopts.progname, getpid(), pthread_self());
bufp += bytes; bufp += bytes;
syslp = bufp; syslp = bufp;
*bufp++ = "DINWEF"[level]; *bufp++ = "DINWEF"[level];

41
test.sh
View file

@ -12654,6 +12654,46 @@ esac
N=$((N+1)) N=$((N+1))
# in version 2.0.0-b7 (and earlier?) dual type addresses terminated when for
# a short time no data was transferred (EOF-timeout)
NAME=DUAL_IDLE
case "$TESTS" in
*%$N%*|*%functions%*|*%bugs%*|*%$NAME%*)
TEST="$NAME: do dual type addresses survive idle phases"
# use a dual type address and check if it transfers data after some idle time
if ! eval $NUMCOND; then :; else
tf="$td/test$N.stdout"
te="$td/test$N.stderr"
tdiff="$td/test$N.diff"
da="test$N $(date) $RANDOM"
CMD0="$SOCAT $opts TCP-LISTEN:$PORT;reuseaddr PIPE"
CMD1="$SOCAT $opts STDOUT%STDIN TCP-CONNECT:$LOCALHOST:$PORT"
printf "test $F_n $TEST... " $N
$CMD0 >/dev/null 2>"${te}0" &
pid0=$!
waittcp4port $PORT 1
(sleep 1; echo "$da") |$CMD1 >"${tf}0" 2>"${te}1"
rc1=$?
kill $pid0 2>/dev/null; wait
if echo "$da" |diff - "${tf}0" >"${tdiff}"; then
$PRINTF "$OK\n"
numOK=$((numOK+1))
else
$PRINTF "$FAILED\n"
echo "$CMD0 &"
echo "$CMD1"
cat "${te}0"
cat "${te}1"
cat "$tdiff"
numFAIL=$((numFAIL+1))
listFAIL="$listFAIL $N"
fi
fi # NUMCOND
;;
esac
PORT=$((PORT+1))
N=$((N+1))
echo "summary: $((N-1)) tests, $((numOK+numFAIL+numCANT)) selected; $numOK ok, $numFAIL failed, $numCANT could not be performed" echo "summary: $((N-1)) tests, $((numOK+numFAIL+numCANT)) selected; $numOK ok, $numFAIL failed, $numCANT could not be performed"
@ -12715,4 +12755,5 @@ fi
fi # NUMCOND fi # NUMCOND
;; ;;
esac esac
#PORT=$((PORT+1))
N=$((N+1)) N=$((N+1))

View file

@ -139,7 +139,7 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
Debug7("data loop: sock1->eof=%d, sock2->eof=%d, 1->closing=%d, 2->closing=%d, wasaction=%d, total_to={"F_tv_sec"."F_tv_usec"}", Debug7("data loop: sock1->eof=%d, sock2->eof=%d, 1->closing=%d, 2->closing=%d, wasaction=%d, total_to={"F_tv_sec"."F_tv_usec"}",
XIO_RDSTREAM(sock1)->eof, XIO_RDSTREAM(sock2)->eof, XIO_RDSTREAM(sock1)->eof, XIO_RDSTREAM(sock2)->eof,
sock1->stream.closing, sock2->stream.closing, XIO_RDSTREAM(sock1)->closing, XIO_RDSTREAM(sock2)->closing,
wasaction, total_timeout.tv_sec, total_timeout.tv_usec); wasaction, total_timeout.tv_sec, total_timeout.tv_usec);
/* for ignoreeof */ /* for ignoreeof */
@ -183,7 +183,7 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
} }
#if 1 #if 1
if (sock1->stream.closing>=1 || sock2->stream.closing>=1) { if (XIO_RDSTREAM(sock1)->closing>=1 || XIO_RDSTREAM(sock2)->closing>=1) {
/* first eof already occurred, start end timer */ /* first eof already occurred, start end timer */
timeout = xioparams->closwait; timeout = xioparams->closwait;
to = &timeout; to = &timeout;
@ -206,22 +206,22 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
closing = 2; closing = 2;
} }
#else #else
if (sock1->stream.closing>=1 || sock2->stream.closing>=1) { if (XIO_RDSTREAM(sock1)->closing>=1 || XIO_RDSTREAM(sock2)->closing>=1) {
/* first eof already occurred, start end timer */ /* first eof already occurred, start end timer */
timeout = xioparams->closwait; timeout = xioparams->closwait;
to = &timeout; to = &timeout;
if (sock1->stream.closing==1) { if (XIO_RDSTREAM(sock1)->closing==1) {
sock1->stream.closing = 2; XIO_RDSTREAM(sock1)->closing = 2;
} }
if (sock2->stream.closing==1) { if (XIO_RDSTREAM(sock2)->closing==1) {
sock2->stream.closing = 2; XIO_RDSTREAM(sock2)->closing = 2;
} }
} }
#endif #endif
/* use the ignoreeof timeout if appropriate */ /* use the ignoreeof timeout if appropriate */
if (polling) { if (polling) {
if ((sock1->stream.closing == 0 && sock2->stream.closing == 0) || if ((XIO_RDSTREAM(sock1)->closing == 0 && XIO_RDSTREAM(sock2)->closing == 0) ||
(xioparams->pollintv.tv_sec < timeout.tv_sec) || (xioparams->pollintv.tv_sec < timeout.tv_sec) ||
((xioparams->pollintv.tv_sec == timeout.tv_sec) && ((xioparams->pollintv.tv_sec == timeout.tv_sec) &&
xioparams->pollintv.tv_usec < timeout.tv_usec)) { xioparams->pollintv.tv_usec < timeout.tv_usec)) {
@ -294,9 +294,9 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
return -1; return -1;
} else if (retval == 0) { } else if (retval == 0) {
Info2("poll timed out (no data within %ld.%06ld seconds)", Info2("poll timed out (no data within %ld.%06ld seconds)",
(sock1->stream.closing>=1||sock2->stream.closing>=1)? (XIO_RDSTREAM(sock1)->closing>=1||XIO_RDSTREAM(sock2)->closing>=1)?
xioparams->closwait.tv_sec:xioparams->total_timeout.tv_sec, xioparams->closwait.tv_sec:xioparams->total_timeout.tv_sec,
(sock1->stream.closing>=1||sock2->stream.closing>=1)? (XIO_RDSTREAM(sock1)->closing>=1||XIO_RDSTREAM(sock2)->closing>=1)?
xioparams->closwait.tv_usec:xioparams->total_timeout.tv_usec); xioparams->closwait.tv_usec:xioparams->total_timeout.tv_usec);
if (polling && !wasaction) { if (polling && !wasaction) {
/* there was a ignoreeof poll timeout, use it */ /* there was a ignoreeof poll timeout, use it */
@ -320,7 +320,7 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
return 0; return 0;
} }
if (sock1->stream.closing || sock2->stream.closing) { if (XIO_RDSTREAM(sock1)->closing || XIO_RDSTREAM(sock2)->closing) {
break; break;
} }
/* one possibility to come here is ignoreeof on some fd, but no EOF /* one possibility to come here is ignoreeof on some fd, but no EOF
@ -377,7 +377,7 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
if ((bytes1 = xiotransfer(sock1, sock2, &buff, xioparams->bufsiz, false)) if ((bytes1 = xiotransfer(sock1, sock2, &buff, xioparams->bufsiz, false))
< 0) { < 0) {
if (errno != EAGAIN) { if (errno != EAGAIN) {
/*sock2->closing = MAX(socks2->closing, 1);*/ /*XIO_RDSTREAM(sock2)->closing = MAX(XIO_RDSTREAM(socks2)->closing, 1);*/
Notice("socket 1 to socket 2 is in error"); Notice("socket 1 to socket 2 is in error");
if (/*0 xioparams->lefttoright*/ !XIO_READABLE(sock2)) { if (/*0 xioparams->lefttoright*/ !XIO_READABLE(sock2)) {
break; break;
@ -400,7 +400,7 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
} }
} }
if (bytes1 == 0) { if (bytes1 == 0) {
if (XIO_RDSTREAM(sock1)->ignoreeof && !sock1->stream.closing) { if (XIO_RDSTREAM(sock1)->ignoreeof && !XIO_RDSTREAM(sock1)->closing) {
; ;
} else { } else {
XIO_RDSTREAM(sock1)->eof = 2; XIO_RDSTREAM(sock1)->eof = 2;
@ -416,7 +416,7 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
if ((bytes2 = xiotransfer(sock2, sock1, &buff, xioparams->bufsiz, true)) if ((bytes2 = xiotransfer(sock2, sock1, &buff, xioparams->bufsiz, true))
< 0) { < 0) {
if (errno != EAGAIN) { if (errno != EAGAIN) {
/*sock1->closing = MAX(sock1->closing, 1);*/ /*XIO_RDSTREAM(sock1)->closing = MAX(XIO_RDSTREAM(sock1)->closing, 1);*/
Notice("socket 2 to socket 1 is in error"); Notice("socket 2 to socket 1 is in error");
if (/*0 xioparams->righttoleft*/ !XIO_READABLE(sock1)) { if (/*0 xioparams->righttoleft*/ !XIO_READABLE(sock1)) {
break; break;
@ -439,7 +439,7 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
} }
} }
if (bytes2 == 0) { if (bytes2 == 0) {
if (XIO_RDSTREAM(sock2)->ignoreeof && !sock2->stream.closing) { if (XIO_RDSTREAM(sock2)->ignoreeof && !XIO_RDSTREAM(sock2)->closing) {
; ;
} else { } else {
XIO_RDSTREAM(sock2)->eof = 2; XIO_RDSTREAM(sock2)->eof = 2;
@ -454,7 +454,7 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
if (bytes1 == 0 || XIO_RDSTREAM(sock1)->eof >= 2) { if (bytes1 == 0 || XIO_RDSTREAM(sock1)->eof >= 2) {
if (XIO_RDSTREAM(sock1)->ignoreeof && if (XIO_RDSTREAM(sock1)->ignoreeof &&
!XIO_RDSTREAM(sock1)->actescape && !sock1->stream.closing) { !XIO_RDSTREAM(sock1)->actescape && !XIO_RDSTREAM(sock1)->closing) {
Debug1("socket 1 (fd %d) is at EOF, ignoring", Debug1("socket 1 (fd %d) is at EOF, ignoring",
XIO_RDSTREAM(sock1)->rfd); /*! */ XIO_RDSTREAM(sock1)->rfd); /*! */
mayrd1 = true; mayrd1 = true;
@ -469,7 +469,7 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
polling = 0; polling = 0;
} }
if (XIO_RDSTREAM(sock1)->eof >= 2) { if (XIO_RDSTREAM(sock1)->eof >= 2) {
sock2->stream.closing = MAX(sock2->stream.closing, 1); XIO_RDSTREAM(sock2)->closing = MAX(XIO_RDSTREAM(sock2)->closing, 1);
if (!XIO_READABLE(sock2)) { if (!XIO_READABLE(sock2)) {
break; break;
} }
@ -477,7 +477,7 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
if (bytes2 == 0 || XIO_RDSTREAM(sock2)->eof >= 2) { if (bytes2 == 0 || XIO_RDSTREAM(sock2)->eof >= 2) {
if (XIO_RDSTREAM(sock2)->ignoreeof && if (XIO_RDSTREAM(sock2)->ignoreeof &&
!XIO_RDSTREAM(sock2)->actescape && !sock2->stream.closing) { !XIO_RDSTREAM(sock2)->actescape && !XIO_RDSTREAM(sock2)->closing) {
Debug1("socket 2 (fd %d) is at EOF, ignoring", Debug1("socket 2 (fd %d) is at EOF, ignoring",
XIO_RDSTREAM(sock2)->rfd); XIO_RDSTREAM(sock2)->rfd);
mayrd2 = true; mayrd2 = true;
@ -492,7 +492,7 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
polling = 0; polling = 0;
} }
if (XIO_RDSTREAM(sock2)->eof >= 2) { if (XIO_RDSTREAM(sock2)->eof >= 2) {
sock1->stream.closing = MAX(sock1->stream.closing, 1); XIO_RDSTREAM(sock1)->closing = MAX(XIO_RDSTREAM(sock1)->closing, 1);
if (!XIO_READABLE(sock1)) { if (!XIO_READABLE(sock1)) {
break; break;
} }