mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 23:42:34 +00:00
Dual type addresses terminated when they were idle for EOF timeout time
This commit is contained in:
parent
7ad17dcd90
commit
6361eec4e9
5 changed files with 65 additions and 22 deletions
2
CHANGES
2
CHANGES
|
@ -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
|
||||||
|
|
|
@ -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@
|
||||||
|
|
2
error.c
2
error.c
|
@ -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
41
test.sh
|
@ -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))
|
||||||
|
|
38
xioengine.c
38
xioengine.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue