From 405a98c0b5d8a909effde90127241cb4559cd2ef Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Mon, 27 Oct 2008 09:24:13 +0100 Subject: [PATCH 1/3] fixes multiple xioshutdown() calls --- test.sh | 30 +++++++++++++++--------------- xioengine.c | 24 ++++++++++++++---------- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/test.sh b/test.sh index 9795efa..48963ef 100755 --- a/test.sh +++ b/test.sh @@ -2207,7 +2207,7 @@ N=$((N+1)) NAME=FILE case "$TESTS" in -*%functions%*|*%file%*|*%ignoreeof%*|*%$NAME%*) +*%functions%*|*%engine%*|*%file%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: simple echo via file" tf="$td/file$N" testecho "$N" "$TEST" "" "$tf%$tf,ignoreeof" "$opts" @@ -3244,7 +3244,7 @@ N=$((N+1)) NAME=GOPENFILE case "$TESTS" in -*%functions%*|*%gopen%*|*%file%*|*%ignoreeof%*|*%$NAME%*) +*%functions%*|*%engine%*|*%gopen%*|*%file%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: file opening with gopen" if ! eval $NUMCOND; then :; else tf1="$td/test$N.1.stdout" @@ -3277,7 +3277,7 @@ N=$((N+1)) NAME=GOPENPIPE case "$TESTS" in -*%functions%*|*%gopen%*|*%pipe%*|*%ignoreeof%*|*%$NAME%*) +*%functions%*|*%engine%*|*%gopen%*|*%pipe%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: pipe opening with gopen for reading" if ! eval $NUMCOND; then :; else tp="$td/pipe$N" @@ -3423,7 +3423,7 @@ N=$((N+1)) #set -vx NAME=IGNOREEOF case "$TESTS" in -*%functions%*|*%ignoreeof%*|*%$NAME%*) +*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: ignoreeof on file" if ! eval $NUMCOND; then :; else ti="$td/test$N.file" @@ -3458,7 +3458,7 @@ set +vx NAME=EXECIGNOREEOF case "$TESTS" in -*%functions%*|*%ignoreeof%*|*%$NAME%*) +*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: exec against address with ignoreeof" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" @@ -4514,7 +4514,7 @@ N=$((N+1)) NAME=TOTALTIMEOUT case "$TESTS" in -*%functions%*|*%timeout%*|*%$NAME%*) +*%functions%*|*%engine%*|*%timeout%*|*%$NAME%*) TEST="$NAME: socat inactivity timeout" if ! eval $NUMCOND; then :; else #set -vx @@ -4553,7 +4553,7 @@ N=$((N+1)) NAME=IGNOREEOF+TOTALTIMEOUT case "$TESTS" in -*%functions%*|*%timeout%*|*%ignoreeof%*|*%$NAME%*) +*%functions%*|*%engine%*|*%timeout%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: ignoreeof and inactivity timeout" if ! eval $NUMCOND; then :; else #set -vx @@ -6187,7 +6187,7 @@ N=$((N+1)) NAME=UNIXTODGRAM case "$TESTS" in -*%functions%*|*%unix%*|*%recv%*|*%$NAME%*) +*%functions%*|*%engine%*|*%unix%*|*%recv%*|*%$NAME%*) TEST="$NAME: generic UNIX client connects to datagram socket" if ! eval $NUMCOND; then :; else ts1="$td/test$N.socket1" @@ -6569,7 +6569,7 @@ fi #false NAME=UNIXDGRAM case "$TESTS" in -*%functions%*|*%unix%*|*%dgram%*|*%$NAME%*) +*%functions%*|*%engine%*|*%unix%*|*%dgram%*|*%$NAME%*) TEST="$NAME: UNIX datagram" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" @@ -6611,7 +6611,7 @@ N=$((N+1)) NAME=UDP4RECV case "$TESTS" in -*%functions%*|*%ip4%*|*%dgram%*|*%udp%*|*%udp4%*|*%recv%*|*%$NAME%*) +*%functions%*|*%engine%*|*%ip4%*|*%dgram%*|*%udp%*|*%udp4%*|*%recv%*|*%$NAME%*) TEST="$NAME: UDP/IPv4 receive" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" @@ -7495,7 +7495,7 @@ N=$((N+1)) NAME=COOLWRITE case "$TESTS" in -*%functions%*|*%timeout%*|*%ignoreeof%*|*%coolwrite%*|*%$NAME%*) +*%functions%*|*%engine%*|*%timeout%*|*%ignoreeof%*|*%coolwrite%*|*%$NAME%*) TEST="$NAME: option cool-write" if ! eval $NUMCOND; then :; elif ! testoptions cool-write >/dev/null; then @@ -7537,7 +7537,7 @@ N=$((N+1)) # this failed up to socat 1.6.0.0 NAME=COOLSTDIO case "$TESTS" in -*%functions%*|*%timeout%*|*%ignoreeof%*|*%coolwrite%*|*%$NAME%*) +*%functions%*|*%engine%*|*%timeout%*|*%ignoreeof%*|*%coolwrite%*|*%$NAME%*) TEST="$NAME: option cool-write on bidirectional stdio" # this test starts a socat reader that terminates after receiving one+ # bytes (option readbytes); and a test process that sends two bytes via @@ -9029,7 +9029,7 @@ N=$((N+1)) # the reverse direction NAME=IGNOREEOFNOBLOCK case "$TESTS" in -*%functions%*|*%socket%*|*%ignoreeof%*|*%$NAME%*) +*%functions%*|*%engine%*|*%socket%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: ignoreeof does not block other direction" # have socat poll in ignoreeof mode. while it waits one second for next check, # we send data in the reverse direction and then the total timeout fires. @@ -9068,7 +9068,7 @@ N=$((N+1)) # test the escape option NAME=ESCAPE case "$TESTS" in -*%functions%*|*%escape%*|*%$NAME%*) +*%functions%*|*%engine%*|*%escape%*|*%$NAME%*) TEST="$NAME: escape character triggers EOF" # idea: start socat just echoing input, but apply escape option. send a string # containing the escape character and check if the output is truncated @@ -9101,7 +9101,7 @@ N=$((N+1)) # test the escape option combined with ignoreeof NAME=ESCAPE_IGNOREEOF case "$TESTS" in -*%functions%*|*%ignoreeof%*|*%escape%*|*%$NAME%*) +*%functions%*|*%engine%*|*%ignoreeof%*|*%escape%*|*%$NAME%*) TEST="$NAME: escape character triggers EOF" # idea: start socat just echoing input, but apply escape option. send a string # containing the escape character and check if the output is truncated diff --git a/xioengine.c b/xioengine.c index 83c9f48..33fcca4 100644 --- a/xioengine.c +++ b/xioengine.c @@ -436,7 +436,7 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) { /* NOW handle EOFs */ - if (bytes1 == 0 || XIO_RDSTREAM(sock1)->eof >= 2) { + if (bytes1 == 0) { if (XIO_RDSTREAM(sock1)->ignoreeof && !XIO_RDSTREAM(sock1)->actescape && !sock1->stream.closing) { Debug1("socket 1 (fd %d) is at EOF, ignoring", @@ -448,16 +448,18 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) { xioshutdown(sock2, SHUT_WR); XIO_RDSTREAM(sock1)->eof = 2; XIO_RDSTREAM(sock1)->ignoreeof = false; - sock2->stream.closing = MAX(sock2->stream.closing, 1); - if (/*0 xioparams->lefttoright*/ !XIO_READABLE(sock2)) { - break; - } } } else if (polling && XIO_RDSTREAM(sock1)->ignoreeof) { polling = 0; } + if (XIO_RDSTREAM(sock1)->eof >= 2) { + sock2->stream.closing = MAX(sock2->stream.closing, 1); + if (!XIO_READABLE(sock2)) { + break; + } + } - if (bytes2 == 0 || XIO_RDSTREAM(sock2)->eof >= 2) { + if (bytes2 == 0) { if (XIO_RDSTREAM(sock2)->ignoreeof && !XIO_RDSTREAM(sock2)->actescape && !sock2->stream.closing) { Debug1("socket 2 (fd %d) is at EOF, ignoring", @@ -469,14 +471,16 @@ int _socat(xiofile_t *xfd1, xiofile_t *xfd2) { xioshutdown(sock1, SHUT_WR); XIO_RDSTREAM(sock2)->eof = 2; XIO_RDSTREAM(sock2)->ignoreeof = false; - sock1->stream.closing = MAX(sock1->stream.closing, 1); - if (/*0 xioparams->righttoleft*/ !XIO_READABLE(sock1)) { - break; - } } } else if (polling && XIO_RDSTREAM(sock2)->ignoreeof) { polling = 0; } + if (XIO_RDSTREAM(sock2)->eof >= 2) { + sock1->stream.closing = MAX(sock1->stream.closing, 1); + if (!XIO_READABLE(sock1)) { + break; + } + } } /* close everything that's still open */ From 634e02269fccf02c4aedba411c2044114284648c Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Tue, 28 Oct 2008 17:48:57 +0100 Subject: [PATCH 2/3] help displayed some option types wrong --- CHANGES | 3 +++ xiohelp.c | 12 ++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 4fe6ee3..efdf410 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,7 @@ +corrections: + help displayed some option types wrong + ####################### V 1.7.0.0: new features: diff --git a/xiohelp.c b/xiohelp.c index fe232cd..090d419 100644 --- a/xiohelp.c +++ b/xiohelp.c @@ -18,19 +18,19 @@ static const char *optiontypenames[] = { "SHORT", "SIZE_T", "SOCKADDR", "UNSIGNED-INT", "UNSIGNED-LONG","UNSIGNED-SHORT","MODE_T", "GID_T", "UID_T", "INT[3]", "STRUCT-TIMEVAL", "STRUCT-TIMESPEC", + "DOUBLE", "STRING-NULL", "LONG-LONG", "OFF_T", + "OFF64_T", "INT:INT", "INT:INTP", "INT:BIN", + "INT:STRING", "INT:INT:INT", "INT:INT:BIN", "INT:INT:STRING", + "IP4NAME", + #if HAVE_STRUCT_LINGER - "STRUCT-LINGER", + "STRUCT-LINGER", #endif - "DOUBLE", "STRING-NULL", "LONG-LONG", - "OFF_T", "OFF64_T", #if HAVE_STRUCT_IP_MREQN "STRUCT-IP_MREQN", #elif HAVE_STRUCT_IP_MREQ "STRUCT-IP_MREQ", #endif - "IP4NAME", - "INT:INT", "INT:INTP", "INT:BIN", "INT:STRING", - "INT:INT:INT", "INT:INT:BIN", "INT:INT:STRING", } ; From 5999bbc1b8b8965e84e5aa60a82499040e731eaf Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Tue, 28 Oct 2008 21:07:47 +0100 Subject: [PATCH 3/3] under some circumstances shutdown was called multiple times for the same fd --- CHANGES | 3 +++ socat.c | 20 ++++++++++++-------- test.sh | 36 ++++++++++++++++++------------------ 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/CHANGES b/CHANGES index efdf410..0d341a1 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ corrections: help displayed some option types wrong + under some circumstances shutdown was called multiple times for the + same fd + ####################### V 1.7.0.0: new features: diff --git a/socat.c b/socat.c index eaa5f37..6abdcb6 100644 --- a/socat.c +++ b/socat.c @@ -1045,14 +1045,16 @@ int _socat(void) { xioshutdown(sock2, SHUT_WR); XIO_RDSTREAM(sock1)->eof = 2; XIO_RDSTREAM(sock1)->ignoreeof = false; - if (socat_opts.lefttoright) { - break; - } - closing = 1; } } else if (polling && XIO_RDSTREAM(sock1)->ignoreeof) { polling = 0; } + if (XIO_RDSTREAM(sock1)->eof >= 2) { + if (socat_opts.lefttoright) { + break; + } + closing = 1; + } if (bytes2 == 0 || XIO_RDSTREAM(sock2)->eof >= 2) { if (XIO_RDSTREAM(sock2)->ignoreeof && @@ -1066,14 +1068,16 @@ int _socat(void) { xioshutdown(sock1, SHUT_WR); XIO_RDSTREAM(sock2)->eof = 2; XIO_RDSTREAM(sock2)->ignoreeof = false; - if (socat_opts.righttoleft) { - break; - } - closing = 1; } } else if (polling && XIO_RDSTREAM(sock2)->ignoreeof) { polling = 0; } + if (XIO_RDSTREAM(sock2)->eof >= 2) { + if (socat_opts.righttoleft) { + break; + } + closing = 1; + } } /* close everything that's still open */ diff --git a/test.sh b/test.sh index 3ff4cfb..66ed015 100755 --- a/test.sh +++ b/test.sh @@ -2149,7 +2149,7 @@ N=$((N+1)) NAME=FILE case "$TESTS" in -*%functions%*|*%file%*|*%ignoreeof%*|*%$NAME%*) +*%functions%*|*%engine%*|*%file%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: simple echo via file" tf="$td/file$N" testecho "$N" "$TEST" "" "$tf,ignoreeof!!$tf" "$opts" @@ -3185,7 +3185,7 @@ N=$((N+1)) NAME=GOPENFILE case "$TESTS" in -*%functions%*|*%gopen%*|*%file%*|*%ignoreeof%*|*%$NAME%*) +*%functions%*|*%engine%*|*%gopen%*|*%file%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: file opening with gopen" if ! eval $NUMCOND; then :; else tf1="$td/test$N.1.stdout" @@ -3364,7 +3364,7 @@ N=$((N+1)) #set -vx NAME=IGNOREEOF case "$TESTS" in -*%functions%*|*%ignoreeof%*|*%$NAME%*) +*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: ignoreeof on file" if ! eval $NUMCOND; then :; else ti="$td/test$N.file" @@ -3399,7 +3399,7 @@ set +vx NAME=EXECIGNOREEOF case "$TESTS" in -*%functions%*|*%ignoreeof%*|*%$NAME%*) +*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: exec against address with ignoreeof" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" @@ -4334,7 +4334,7 @@ N=$((N+1)) NAME=TOTALTIMEOUT case "$TESTS" in -*%functions%*|*%timeout%*|*%$NAME%*) +*%functions%*|*%engine%*|*%timeout%*|*%$NAME%*) TEST="$NAME: socat inactivity timeout" if ! eval $NUMCOND; then :; else #set -vx @@ -4373,7 +4373,7 @@ N=$((N+1)) NAME=IGNOREEOF+TOTALTIMEOUT case "$TESTS" in -*%functions%*|*%timeout%*|*%ignoreeof%*|*%$NAME%*) +*%functions%*|*%engine%*|*%timeout%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: ignoreeof and inactivity timeout" if ! eval $NUMCOND; then :; else #set -vx @@ -4412,7 +4412,7 @@ N=$((N+1)) NAME=PROXY2SPACES case "$TESTS" in -*%functions%*|*%$NAME%*) +*%functions%*|*%proxy%*|*%$NAME%*) TEST="$NAME: proxy connect accepts status with multiple spaces" if ! eval $NUMCOND; then :; elif ! testaddrs proxy >/dev/null; then @@ -4707,7 +4707,7 @@ N=$((N+1)) #! NAME=OUTBOUNDIN case "$TESTS" in -*%functions%*|*%$NAME%*) +*%functions%*|*%proxy%*|*%$NAME%*) TEST="$NAME: gender changer via SSL through HTTP proxy, oneshot" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs openssl proxy); then @@ -4792,7 +4792,7 @@ PORT=$((RANDOM+16184)) #! NAME=INTRANETRIPPER case "$TESTS" in -*%functions%*|*%$NAME%*) +*%functions%*|*%proxy%*|*%$NAME%*) TEST="$NAME: gender changer via SSL through HTTP proxy, daemons" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs openssl proxy); then @@ -5995,7 +5995,7 @@ N=$((N+1)) NAME=UNIXTODGRAM case "$TESTS" in -*%functions%*|*%unix%*|*%recv%*|*%$NAME%*) +*%functions%*|*%engine%*|*%unix%*|*%recv%*|*%$NAME%*) TEST="$NAME: generic UNIX client connects to datagram socket" if ! eval $NUMCOND; then :; else ts1="$td/test$N.socket1" @@ -6377,7 +6377,7 @@ fi #false NAME=UNIXDGRAM case "$TESTS" in -*%functions%*|*%unix%*|*%dgram%*|*%$NAME%*) +*%functions%*|*%engine%*|*%unix%*|*%dgram%*|*%$NAME%*) TEST="$NAME: UNIX datagram" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" @@ -6419,7 +6419,7 @@ N=$((N+1)) NAME=UDP4RECV case "$TESTS" in -*%functions%*|*%ip4%*|*%dgram%*|*%udp%*|*%udp4%*|*%recv%*|*%$NAME%*) +*%functions%*|*%engine%*|*%ip4%*|*%dgram%*|*%udp%*|*%udp4%*|*%recv%*|*%$NAME%*) TEST="$NAME: UDP/IPv4 receive" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" @@ -7304,7 +7304,7 @@ N=$((N+1)) NAME=COOLWRITE case "$TESTS" in -*%functions%*|*%timeout%*|*%ignoreeof%*|*%coolwrite%*|*%$NAME%*) +*%functions%*|*%engine%*|*%timeout%*|*%ignoreeof%*|*%coolwrite%*|*%$NAME%*) TEST="$NAME: option cool-write" if ! eval $NUMCOND; then :; elif ! testoptions cool-write >/dev/null; then @@ -7346,7 +7346,7 @@ N=$((N+1)) # this failed up to socat 1.6.0.0 NAME=COOLSTDIO case "$TESTS" in -*%functions%*|*%timeout%*|*%ignoreeof%*|*%coolwrite%*|*%$NAME%*) +*%functions%*|*%engine%*|*%timeout%*|*%ignoreeof%*|*%coolwrite%*|*%$NAME%*) TEST="$NAME: option cool-write on bidirectional stdio" # this test starts a socat reader that terminates after receiving one+ # bytes (option readbytes); and a test process that sends two bytes via @@ -7682,7 +7682,7 @@ NAME=IP4BROADCAST # because we receive - in addition to the regular reply - our own broadcast, # we use a token XXXX that is changed to YYYY in the regular reply packet. case "$TESTS" in -*%functions%*|*%rawip%*|*%rawip4%*|*%ip4%*|*%dgram%*|*%broadcast%*|*%root%*|*%$NAME%*) +*%functions%*|*%engine%*|*%rawip%*|*%rawip4%*|*%ip4%*|*%dgram%*|*%broadcast%*|*%root%*|*%$NAME%*) TEST="$NAME: raw IPv4 broadcast" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip4 rawip) || ! runsip4 >/dev/null; then @@ -8809,7 +8809,7 @@ N=$((N+1)) # the reverse direction NAME=IGNOREEOFNOBLOCK case "$TESTS" in -*%functions%*|*%socket%*|*%ignoreeof%*|*%$NAME%*) +*%functions%*|*%engine%*|*%socket%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: ignoreeof does not block other direction" # have socat poll in ignoreeof mode. while it waits one second for next check, # we send data in the reverse direction and then the total timeout fires. @@ -8848,7 +8848,7 @@ N=$((N+1)) # test the escape option NAME=ESCAPE case "$TESTS" in -*%functions%*|*%escape%*|*%$NAME%*) +*%functions%*|*%engine%*|*%escape%*|*%$NAME%*) TEST="$NAME: escape character triggers EOF" # idea: start socat just echoing input, but apply escape option. send a string # containing the escape character and check if the output is truncated @@ -8881,7 +8881,7 @@ N=$((N+1)) # test the escape option combined with ignoreeof NAME=ESCAPE_IGNOREEOF case "$TESTS" in -*%functions%*|*%ignoreeof%*|*%escape%*|*%$NAME%*) +*%functions%*|*%engine%*|*%ignoreeof%*|*%escape%*|*%$NAME%*) TEST="$NAME: escape character triggers EOF" # idea: start socat just echoing input, but apply escape option. send a string # containing the escape character and check if the output is truncated