How to make `nc` listen on a port without setting `SO_REUSEPORT`

netcatportsocattcpip

I want to have a nc command listen on a TCP port so I did:

nc -lv 8888

Then in another console I checked if another program trying to listen on the same port would get an Address already in use type of error so I issued the same command again:

nc -lv 8888

To my surprise the second command also succeeded. Investigating how 2 programs can be listening on the same TCP port, I found that's possible if the listening socket is opened with the option SO_REUSEPORT, so I imagine nc is using it.

How can I make nc disallow other programs to use its same port? I'd like it to listen on port 8888 and make sure that's the only program that will be listening on that port.

So far I've been able to do what I want by introducing socat along nc like this:

socat TCP-LISTEN:8888,fork TCP:localhost:4444
nc -lv 4444

Because socat disallows any other program from listening on the same port.

But is it possible to accomplish this with only nc?

Best Answer

Looking to one of the netcat source code netcat.c in the method local_listen :

        ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
        if (ret == -1)
            err(1, NULL);

# if defined(SO_REUSEPORT)
        ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
        if (ret == -1)
            err(1, NULL);
# endif

Then in order to modify the behaviour, you need to modify the code.

However I made a test with netcat-openbsd 1.105-7 that is part of Ubuntu Xenial and it seems built without defining SO_REUSEPORT. As it set SO_REUSEADDR but not the SO_REUSEPORT (under a kernel > 3.9) it works like you expect refusing to run a second intance on same port.

Related Question