Nmap Development mailing list archives

Re: ncat: terminate when remote EOF


From: Fyodor <fyodor () nmap org>
Date: Sat, 3 Jun 2017 19:13:05 -0700

On Tue, May 9, 2017 at 12:21 AM, Matthias Wächter <matthias () waechter wiz at>
wrote:


Take for example, a simple HTTP session. When I have told the server what
page I want to receive, i.e., sending GET, Host: and empty line, and the
server has returned the data, the server closes its end of the connection.
Using "telnet server 80", or "nc server 80", or even "socat -
TCP:server:80" for that, all lead to the same result: When the server is
done, the program exits. In this discipline, telnet and nc are the fastest,
terminating without any delay, and socat offers the option "-t" to specify
the delay between EOF and termination. Specifying "-t0" brings socat to the
same zero-delay like telnet and nc.

Not so with ncat. After the server has sent the data and is obviously
done, the session stays open until either (a) the client terminates it, or
(b) sends additional data, which then breaks the pipe, or (c) -i <timeout>
was specified, and that inactivity timeout ran out.


Well, it's obvious that the server is done sending data because that side
of the socket has been closed (we generally detect this with a zero byte
read).  But Ncat has not received an EOF from it's stdin yet, so you might
have more to write.  And for all Ncat knows, the server may still be
listening for that remaining data.  Here's an admittedly contrived example:

Let's say I decide to abandon network security and start selling hamburgers
instead.  So of course I use Ncat to take orders over the Internet as so:

[fyodor@hax ~]$ echo "Welcome to Fyodor Burger Shack. What would you like?"
| ncat -v -l -p 8881 > order
Ncat: Version 7.40SVN ( https://nmap.org/ncat )
Ncat: Listening on :::8881
Ncat: Listening on 0.0.0.0:8881

So, as you can see, I'm asking Ncat server to print out a quick greeting to
the first client that connects, accept the order from the client, and store
it in the "order" file.  If I try to use this system with telnet, it fails:

[fyodor@hax ~]$ telnet localhost 8881
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Welcome to Fyodor Burger Shack. What would you like?
Connection closed by foreign host.

Telnet received the EOF (zero byte receive) from the server after the
greeting was printed and then it bailed immediately even though the server
would have happily accepted the order.  But if we restart the server and
then try with Ncat client, it works fine:

[fyodor@hax ~]$ ncat -v localhost 8881
Ncat: Version 7.40SVN ( https://nmap.org/ncat )
Ncat: Connected to 127.0.0.1:8881.
Welcome to Fyodor Burger Shack. What would you like?
2 ACKBurgers with extra flags
1 large fries
Ncat: 44 bytes sent, 53 bytes received in 8.52 seconds.

(I pressed ^D after the large fries so Ncat would get EOF and know I was
done writing).

While the current behavior is useful in this totally contrived example, I'm
not sure offhand how important it is in the real world.  And I can
certainly see the value you've noted in immediately quitting the connection
upon remove EOF like telnet and apparently OpenBSD nc do.

The perfect fix might be to detect somehow whether the remote server is
still listening for data or has shutdown both directions.  But I don't know
that there is a way to do this without actually trying to send more data.
So, barring that, Dan's suggestion to close immediately when the server is
done sending might be the best approach.  At least if nobody can give a
compelling reason to keep this default behavior.  Allowing the -k option to
bring back the (current) keep alive behavior in client mode seems like a
good compromise to preserve the behavior for anyone who needs it.

Cheers,
Fyodor
_______________________________________________
Sent through the dev mailing list
https://nmap.org/mailman/listinfo/dev
Archived at http://seclists.org/nmap-dev/

Current thread: