mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 15:32:35 +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()
|
||||
|
||||
Dual type addresses terminated when they were idle for EOF timeout time
|
||||
|
||||
porting:
|
||||
Red Hat issue 1020203: configure checks fail with some compilers.
|
||||
Use case: clang
|
||||
|
|
|
@ -22,8 +22,8 @@ srcdir = @srcdir@
|
|||
VPATH = @srcdir@
|
||||
|
||||
CC = @CC@
|
||||
CCOPTS = $(CCOPT) -Wall -Wno-parentheses
|
||||
CCOPTS = $(CCOPT)
|
||||
#CCOPTS = $(CCOPT) -Wall -Wno-parentheses
|
||||
CCOPTS = $(CCOPT) -pthread
|
||||
|
||||
SYSDEFS = @SYSDEFS@
|
||||
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["F_pid".%lu] ",
|
||||
diagopts.progname, getpid(), (unsigned long)pthread_self());
|
||||
diagopts.progname, getpid(), pthread_self());
|
||||
bufp += bytes;
|
||||
syslp = bufp;
|
||||
*bufp++ = "DINWEF"[level];
|
||||
|
|
41
test.sh
41
test.sh
|
@ -12654,6 +12654,46 @@ esac
|
|||
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"
|
||||
|
||||
|
@ -12715,4 +12755,5 @@ fi
|
|||
fi # NUMCOND
|
||||
;;
|
||||
esac
|
||||
#PORT=$((PORT+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"}",
|
||||
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);
|
||||
|
||||
/* for ignoreeof */
|
||||
|
@ -183,7 +183,7 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
|
|||
}
|
||||
|
||||
#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 */
|
||||
timeout = xioparams->closwait;
|
||||
to = &timeout;
|
||||
|
@ -206,22 +206,22 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
|
|||
closing = 2;
|
||||
}
|
||||
#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 */
|
||||
timeout = xioparams->closwait;
|
||||
to = &timeout;
|
||||
if (sock1->stream.closing==1) {
|
||||
sock1->stream.closing = 2;
|
||||
if (XIO_RDSTREAM(sock1)->closing==1) {
|
||||
XIO_RDSTREAM(sock1)->closing = 2;
|
||||
}
|
||||
if (sock2->stream.closing==1) {
|
||||
sock2->stream.closing = 2;
|
||||
if (XIO_RDSTREAM(sock2)->closing==1) {
|
||||
XIO_RDSTREAM(sock2)->closing = 2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* use the ignoreeof timeout if appropriate */
|
||||
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_usec < timeout.tv_usec)) {
|
||||
|
@ -294,9 +294,9 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
|
|||
return -1;
|
||||
} else if (retval == 0) {
|
||||
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,
|
||||
(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);
|
||||
if (polling && !wasaction) {
|
||||
/* there was a ignoreeof poll timeout, use it */
|
||||
|
@ -320,7 +320,7 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (sock1->stream.closing || sock2->stream.closing) {
|
||||
if (XIO_RDSTREAM(sock1)->closing || XIO_RDSTREAM(sock2)->closing) {
|
||||
break;
|
||||
}
|
||||
/* 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))
|
||||
< 0) {
|
||||
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");
|
||||
if (/*0 xioparams->lefttoright*/ !XIO_READABLE(sock2)) {
|
||||
break;
|
||||
|
@ -400,7 +400,7 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
|
|||
}
|
||||
}
|
||||
if (bytes1 == 0) {
|
||||
if (XIO_RDSTREAM(sock1)->ignoreeof && !sock1->stream.closing) {
|
||||
if (XIO_RDSTREAM(sock1)->ignoreeof && !XIO_RDSTREAM(sock1)->closing) {
|
||||
;
|
||||
} else {
|
||||
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))
|
||||
< 0) {
|
||||
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");
|
||||
if (/*0 xioparams->righttoleft*/ !XIO_READABLE(sock1)) {
|
||||
break;
|
||||
|
@ -439,7 +439,7 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
|
|||
}
|
||||
}
|
||||
if (bytes2 == 0) {
|
||||
if (XIO_RDSTREAM(sock2)->ignoreeof && !sock2->stream.closing) {
|
||||
if (XIO_RDSTREAM(sock2)->ignoreeof && !XIO_RDSTREAM(sock2)->closing) {
|
||||
;
|
||||
} else {
|
||||
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 (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",
|
||||
XIO_RDSTREAM(sock1)->rfd); /*! */
|
||||
mayrd1 = true;
|
||||
|
@ -469,7 +469,7 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
|
|||
polling = 0;
|
||||
}
|
||||
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)) {
|
||||
break;
|
||||
}
|
||||
|
@ -477,7 +477,7 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
|
|||
|
||||
if (bytes2 == 0 || XIO_RDSTREAM(sock2)->eof >= 2) {
|
||||
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",
|
||||
XIO_RDSTREAM(sock2)->rfd);
|
||||
mayrd2 = true;
|
||||
|
@ -492,7 +492,7 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) {
|
|||
polling = 0;
|
||||
}
|
||||
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)) {
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue