Netcat stops listening for UDP traffic

Posted on

Problem :

I am using netcat on some Linux machines (see this other question), but seeing some unexpected behavior.

Unlike the guide in the accepted answer, I am not using UDP tunneling to do DNS queries. I have a remote server that I can log into, but not install software on, and I’m trying to tunnel UDP traffic from my computer to the server, and then setup a separate tunnel to send UDP responses back from the server to my machine.

The tunnel going from my machine to the server is working perfectly, however on the server side, the instance of netcat that is listening for the response from the UDP server will close the listener after receiving the first response. So I can send a request and get 1 response back, but any subsequent requests make it to the server okay but responses are not received. Using netstat I can see that before the response is received netcat is listening, but the port is then closed after the response is received.

The netcat instance on my machine seems to handle everything just fine. Both machines are running netcat v1.10-38. Any ideas what is going on?

Solution :

So there are multiple things called netcat; ubuntu even has /etc/alternatives symbolic-link-hackery for it.

I think part of your problem is that UDP doesn’t do sessions; I’ve copied in part of the file /usr/share/doc/netcat-traditional/README.gz below which does a pretty good job of explaining.

UDP connections are opened instead of
TCP when -u is specified. These
aren’t really “connections” per se
since UDP is a connectionless
protocol, although netcat does
internally use the “connected UDP
socket” mechanism that most kernels
support. Although netcat claims that
an outgoing UDP connection is “open”
immediately, no data is sent until
something is read from standard input.
Only thereafter is it possible to
determine whether there really is a
UDP server on the other end, and often
you just can’t tell. Most UDP
protocols use timeouts and retries to
do their thing and in many cases won’t
bother answering at all, so you should
specify a timeout and hope for the
best. You will get more out of UDP
connections if standard input is fed
from a source of data that looks like
various kinds of server requests.

OK so maybe that’s not all that great of an explanation but it’s what I could find.

If you haven’t yet, you might want to experiment with any netcat options you can find that would have to do with waiting… have you experimented with:

  • using -l as well as -u to ensure you’re in “listening” mode

  • -vv to see exactly what’s happening

  • -q -1 …which should “wait forever” even after receiving EOF (hopefully, listening again?)

You can use socat for that. It has very nice option fork:

fork After establishing a connection, handles its channel in a child process and keeps the parent process attempting to produce more connections, either by listening or by connecting in a loop (example).

Client (yes this you run from the client):

$ ssh -L 7753:localhost:7753 "/usr/bin/socat tcp4-listen:7753,reuseaddr,fork UDP:"


$ sudo socat udp4-listen:53,reuseaddr,fork tcp:localhost:7753
$ dig @

Leave a Reply

Your email address will not be published. Required fields are marked *