This service will be undergoing maintenance at 00:00 UTC, 2016-08-01. It is expected to last about 1 hours
Bug 905484 - ncat terminates the transaction before all data were sent
ncat terminates the transaction before all data were sent
Status: CLOSED CURRENTRELEASE
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: nmap (Show other bugs)
7.0
Unspecified Unspecified
medium Severity medium
: beta
: ---
Assigned To: Michal Hlavinka
Jiri Jaburek
: Regression
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2013-01-29 08:55 EST by Patrik Kis
Modified: 2014-06-13 08:04 EDT (History)
2 users (show)

See Also:
Fixed In Version: nmap-6.40-2.el7
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2014-06-13 08:04:15 EDT
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:


Attachments (Terms of Use)
Patch to fix TCP issue based on latest upstream SVN (1.10 KB, patch)
2013-02-07 03:53 EST, Tomas Hozza
no flags Details | Diff
Patch for Ncat's testsuite to reflect changes in behaviour (1.89 KB, patch)
2013-02-08 03:09 EST, Tomas Hozza
no flags Details | Diff

  None (edit)
Description Patrik Kis 2013-01-29 08:55:05 EST
Description of problem:
ncat many times terminates the TCP or STCP transaction before all data were sent.
Typically in a client/server connection only one side send all data, then immediately call for connection close, what is all right, but the other side accept the connection and do not send its data prior to closure, what is not correct.
Moreover, this used to work on RHEL-6 as expected, so this can be considered as regression.

Version-Release number of selected component (if applicable):
nmap-6.01-9.el7

How reproducible:
~ 90%
On x86_64 usually only SCTP fail, but on x390x and ppc64 also TCP.

Steps to Reproduce:
1. Server:
# echo ServerSend |ncat -vl 6666
2. Client:
# echo ClientSend |ncat -4 localhost 6666
  
Actual results:
# echo ServerSend |ncat -vl 6666
Ncat: Version 6.01 ( http://nmap.org/ncat )
Ncat: Listening on :::6666
Ncat: Listening on 0.0.0.0:6666
Ncat: Connection from 127.0.0.1.
Ncat: Connection from 127.0.0.1:49443.

# echo ClientSend |ncat -4 localhost 6666
ServerSend

tcpdump log:
09:01:45.302208 IP 127.0.0.1.45784 > 127.0.0.1.6666: Flags [S], seq 1841093145, win 43690, options [mss 65495,sackOK,TS val 810970 ecr 0,nop,wscale 7], length 0
09:01:45.302238 IP 127.0.0.1.6666 > 127.0.0.1.45784: Flags [S.], seq 1977777676, ack 1841093146, win 43690, options [mss 65495,sackOK,TS val 810970 ecr 810970,nop,wscale 7], length 0
09:01:45.302265 IP 127.0.0.1.45784 > 127.0.0.1.6666: Flags [.], ack 1, win 342, options [nop,nop,TS val 810970 ecr 810970], length 0
09:01:45.302593 IP 127.0.0.1.6666 > 127.0.0.1.45784: Flags [P.], seq 1:12, ack 1, win 342, options [nop,nop,TS val 810970 ecr 810970], length 11
09:01:45.302619 IP 127.0.0.1.6666 > 127.0.0.1.45784: Flags [F.], seq 12, ack 1, win 342, options [nop,nop,TS val 810970 ecr 810970], length 0
09:01:45.302733 IP 127.0.0.1.45784 > 127.0.0.1.6666: Flags [.], ack 12, win 342, options [nop,nop,TS val 810970 ecr 810970], length 0
09:01:45.302920 IP 127.0.0.1.45784 > 127.0.0.1.6666: Flags [F.], seq 1, ack 13, win 342, options [nop,nop,TS val 810971 ecr 810970], length 0
09:01:45.302938 IP 127.0.0.1.6666 > 127.0.0.1.45784: Flags [.], ack 2, win 342, options [nop,nop,TS val 810971 ecr 810971], length 0

The same for SCTP:
09:01:52.892627 IP 127.0.0.1.48129 > 127.0.0.1.6666: sctp (1) [INIT] [init tag: 940470389] [rwnd: 106496] [OS: 10] [MIS: 65535] [init TSN: 2747800073] 
09:01:52.892703 IP 127.0.0.1.6666 > 127.0.0.1.48129: sctp (1) [INIT ACK] [init tag: 832624771] [rwnd: 106496] [OS: 10] [MIS: 10] [init TSN: 1133244985] 
09:01:52.892719 IP 127.0.0.1.48129 > 127.0.0.1.6666: sctp (1) [COOKIE ECHO] 
09:01:52.892754 IP 127.0.0.1.6666 > 127.0.0.1.48129: sctp (1) [COOKIE ACK] 
09:01:52.893063 IP 127.0.0.1.6666 > 127.0.0.1.48129: sctp (1) [DATA] (B)(E) [TSN: 1133244985] [SID: 0] [SSEQ 0] [PPID 0x0] 
09:01:52.893115 IP 127.0.0.1.48129 > 127.0.0.1.6666: sctp (1) [SACK] [cum ack 1133244985] [a_rwnd 106485] [#gap acks 0] [#dup tsns 0] 
09:01:52.893130 IP 127.0.0.1.6666 > 127.0.0.1.48129: sctp (1) [SHUTDOWN] 
09:01:52.893169 IP 127.0.0.1.48129 > 127.0.0.1.6666: sctp (1) [SHUTDOWN ACK] 
09:01:52.893181 IP 127.0.0.1.6666 > 127.0.0.1.48129: sctp (1) [SHUTDOWN COMPLETE] 


Expected results:

16:53:44.484069 IP 127.0.0.1.44939 > 127.0.0.1.6666: Flags [S], seq 1369395444, win 43690, options [mss 65495,sackOK,TS val 4294944286 ecr 0,nop,wscale 7], length 0
16:53:44.484094 IP 127.0.0.1.6666 > 127.0.0.1.44939: Flags [S.], seq 3259413553, ack 1369395445, win 43690, options [mss 65495,sackOK,TS val 4294944286 ecr 4294944286,nop,wscale 7], length 0
16:53:44.484107 IP 127.0.0.1.44939 > 127.0.0.1.6666: Flags [.], ack 1, win 342, options [nop,nop,TS val 4294944286 ecr 4294944286], length 0
16:53:44.484165 IP 127.0.0.1.44939 > 127.0.0.1.6666: Flags [P.], seq 1:12, ack 1, win 342, options [nop,nop,TS val 4294944286 ecr 4294944286], length 11
16:53:44.484176 IP 127.0.0.1.6666 > 127.0.0.1.44939: Flags [.], ack 12, win 342, options [nop,nop,TS val 4294944286 ecr 4294944286], length 0
16:53:44.484193 IP 127.0.0.1.44939 > 127.0.0.1.6666: Flags [F.], seq 12, ack 1, win 342, options [nop,nop,TS val 4294944286 ecr 4294944286], length 0
16:53:44.484225 IP 127.0.0.1.6666 > 127.0.0.1.44939: Flags [P.], seq 1:12, ack 13, win 342, options [nop,nop,TS val 4294944286 ecr 4294944286], length 11
16:53:44.484259 IP 127.0.0.1.44939 > 127.0.0.1.6666: Flags [.], ack 12, win 342, options [nop,nop,TS val 4294944286 ecr 4294944286], length 0
16:53:44.484300 IP 127.0.0.1.6666 > 127.0.0.1.44939: Flags [F.], seq 12, ack 13, win 342, options [nop,nop,TS val 4294944286 ecr 4294944286], length 0
16:53:44.484309 IP 127.0.0.1.44939 > 127.0.0.1.6666: Flags [.], ack 13, win 342, options [nop,nop,TS val 4294944286 ecr 4294944286], length 0

Additional info:
Note, the issue is not on client side only as it might looks like, I've seen also a trace where the client sent the data and the server not (I think it was for sctp).
Comment 3 Tomas Hozza 2013-02-06 10:48:25 EST
(In reply to comment #0)
> Description of problem:
> ncat many times terminates the TCP or STCP transaction before all data were sent.
> Typically in a client/server connection only one side send all data, then
> immediately call for connection close, what is all right, but the other side
> accept the connection and do not send its data prior to closure, what is not
> correct.
> Moreover, this used to work on RHEL-6 as expected, so this can be considered
> as regression.

For TCP, this is true, but nc in RHEL-6 does NOT support SCTP at all!

> Additional info:
> Note, the issue is not on client side only as it might looks like, I've seen
> also a trace where the client sent the data and the server not (I think it
> was for sctp).

Described issue can be fixed for TCP connections. But in case of SCTP connection this
is more complicated. In fact ncat's behaviour can NOT be the same for TCP and SCTP.
The problem is that SCTP's design does NOT provide half-closed connection as TCP does.

So in case of TCP (after fix):
If server reads EOF from STDIN it calls shutdown(<socket_fd>, SHUT_WR). This will cause
client to read EOF from socket and indicate that no more data are coming from
the server. But the connection still remains half-opened. This means client
can still send some data to server. After client reads EOF from STDIN it also
calls shutdown(<socket_fd>, SHUT_WR). This will cause the client to close the connection.
The same applies if you switch server with client.

In case of SCTP (current behaviour):
If server reads EOF from STDIN it calls shutdown(<socket_fd>, SHUT_WR). This will cause
client to read EOF from socket and indicate that no more data are coming from
the server. But moreover this call (and also just sending EOF to the client)
will trigger SCTP connection shutdown procedure initiated by the server. Client has
to proceed with the shutdown and no more data can be send through the socket
after receiving EOF. This procedure is handled by the kernel SCTP stack.

In the current implementation client will "think" that it can still send some data
to server. But writing to the socket will FAIL since the connection was closed.
It will result into a "broken pipe" error and causes client to crash.
The same applies if you switch server with client.


I see four possibilities of ncat's behaviour if SCTP is used:

1. -----------------------------------------------------------
If server reads EOF from STDIN it will NOT call shutdown(<socket_fd>, SHUT_WR).
Server will not respond to any further input from STDIN. Bad thing about this is
that client will NOT "know" that no more data are coming from the server.
So now if client reads EOF from STDIN it can NOT call shutdown(<socket_fd>, SHUT_WR),
too. It would cause the connection to close but there may be more data coming
from the server (at least client "thinks" this since it did not receive any EOF)!
So client will not respond to any further input from STDIN either. This will result
in client and server not responding to any input from STDIN and waiting for some
incoming data that will never come. It is kind of a deadlock.
The same applies if you switch server with client.

Pros: no data sent by client/server will be lost.
Cons: can result in kind of a deadlock.

2. -----------------------------------------------------------
If server reads EOF from STDIN it will exit the listening loop causing the connection
to close. If client reads EOF on STDIN it will just not respond to any further input
from STDIN, but will do nothing with the connection. Bad thing about this is that
data from client will be lost if server closes the connection before client sends them.

Pros: no data sent by server will be lost.
      can NOT result in a deadlock
Cons: data not sent by client before server closes the connection will be lost.

3. -----------------------------------------------------------
If server reads EOF on STDIN it will just not respond to any further input
from STDIN, but will do nothing with the connection. If client reads EOF on STDIN
it will close the connection. Bad thing about this is that data from server will
be lost if client closes the connection before server sends them.

Pros: no data sent by client will be lost.
      can NOT result in a deadlock
Cons: data not sent by server before client closes the connection will be lost.

4. -----------------------------------------------------------
If server reads EOF on STDIN it will exit the listening loop causing the connection
to close. If client reads EOF on STDIN it will close the connection. Bad thing about
this is that data from server(client) will be lost if client(server) closes the
connection before server(client) sends them.

Pros: can NOT result in a deadlock
Cons: data not sent by server(client) before client(server) closes the connection will be lost.


There needs to be some more discussion about what should be the proper ncat's behaviour
for SCTP. I will forward this message to the upstream devel mailing-list.

I will also prepare a scratch build with fixed TCP behaviour for you to test.
Comment 4 Tomas Hozza 2013-02-07 03:53:58 EST
Created attachment 694300 [details]
Patch to fix TCP issue based on latest upstream SVN

Patch sent to upstream
Comment 10 Tomas Hozza 2013-02-08 03:09:50 EST
Created attachment 694979 [details]
Patch for Ncat's testsuite to reflect changes in behaviour

Patch sent to upstream.
Comment 13 Ludek Smid 2014-06-13 08:04:15 EDT
This request was resolved in Red Hat Enterprise Linux 7.0.

Contact your manager or support representative in case you have further questions about the request.

Note You need to log in before you can comment on or make changes to this bug.