Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What exactly does the -q option of netcat do?

I have a service whose behavior I've been debugging behind a proxy. The proxy is a black box, but the service's behavior can be simulated with a trivial python program like below:

#!/usr/bin/env python

import socket
import sys
import time

PORT = int(sys.argv[1] or 50007)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
    s.bind(('', PORT))
    s.listen(1)
    conn, addr = s.accept()
    print('conn from %s' % (addr,))
    data = conn.recv(1024)
    time.sleep(1)
    conn.sendall(data)
finally:
    conn.close()
    s.close()

When I connect to this directly with netcat, I get the expected behavior, which is that after sending some arbitrary text to stdin with a newline, the server delays for a second, echoes it back, and closes the connection. However, when I put this service behind the proxy, netcat instead immediately exits with status 0, unless I give it the -q option with some nonzero number, after which it behaves the same as the direct connection.

To quote from the manpage for netcat on my system:

-q      after EOF on stdin, wait the specified number of seconds and then quit.
        If seconds is negative, wait forever.

What I'm trying to debug is what is different about the proxy connection behavior that would cause the connection behavior to differ with the -q option, and unfortunately, the man page isn't doing much to help me out. What is the "stdin" it's referring to, if it's not my input (which never receives an EOF from me)? What EOF is -q ignoring for long enough to receive the proxy'd data back from that it doesn't have to ignore when there is no proxy mediating the connection?

EDIT: On request, here are some sample invocations, although they're about as basic as it gets:

# after starting the example server on <someserver> with <someport

$ echo foo | nc <someserver> <someport>
foo
$

# the above, just with -q1 (no change)
$ echo foo | nc -q1 <someserver> <someport>
foo
$

# after starting the example server behind the blackbox proxy
$ echo foo | nc <someproxy> <someproxyport>
$

# same, but with -q
$ echo foo | nc -q1 <someproxy> <someproxyport>
foo
$
like image 461
A. Wilson Avatar asked Jan 21 '17 07:01

A. Wilson


1 Answers

echo foo | netcat sends EOF in all cases. What differs is the way netcat closes its network socket.

Without -q netcat sends TCP FIN right after receiving EOF, shutting down its half of TCP connection. That is not a full connection closing, just an indication that no more data will be sent. After that netcat keeps printing data from the connection until it closes.

Normal server does not handle FIN from netcat, delays, sends echo response and then shuts down the last half of connection.

The blackbox proxy seems to react on FIN from client by closing connection immediately. That might be some kind of server load optimization, which has a sense in case with lots of web browsers, for example.

With -q netcat does not send FIN until connection is closed by the server or until -q timeout ends.

Run your four cases under tcpdump -w, then load capture file in Wireshark, follow TCP stream and see the difference. Be aware that this netcat behaviour might depend on a particular version, I confirm it for Ubuntu 16.04 + netcat-openbsd 1.105.

like image 162
void Avatar answered Oct 21 '22 18:10

void