0

I have a Java socket server that was created with ephemeral port (bind with port 0) on "localhost". However, after it is up and running, the netstat shows that there is another process listening to the same port on any interface.

Here is netstat output:

$ sudo netstat -n -a -p | grep 34797
tcp6       0  0   127.0.0.1:34797     :::*        LISTEN      4210/java
tcp6       0  0   :::34797            :::*        LISTEN      -         

Using rpcinfo, I confirm that it is the NFS nlockmgr. I can reproduce the issue with the socket server binds to the same 34797 port explicitly.

It is only true for ports used by NFS services (rpc.mountd, nlockmgr). If I try to do the same with a port already bind on the :: any interface by an existing application, it will result in bind "Address already in use" error, which is what I expected.

This is problematic for me as it messes up the service that I am running for receiving requests.

My question is, why the NFS services are so special and why does Linux allow this to happen (by allocating an ephemeral port that is already in use)?

0

In general, what you're experiencing can be regular when IPv6 is involved.

In your case the "any address" bound is the IPv6 one, while the "localhost" address bound is the IPv4 one. This is perfectly regular if the application bound to the IPv6 "any address" has set the IPV6_V6ONLY socket option.

On Linux there is also a system-wide default value for that option, which can be viewed and set in /proc/sys/net/ipv6/bindv6only and whose default is 0 thus making IPv4 and IPv6 share the TCP/UDP port numbers space.

Note also that the fact that your 127.0.0.1:34797 LISTEN socket is marked tcp6 is irrelevant to this purpose, because it is considered an IPv4 address even if it is backed by the IPv6 networking stack. This too is standard-compliant behavior.

The outcome in your case is that TCP connections to 127.0.0.1:34797 will be delivered to your java application, while connections to that same port but to any of your machine's IPv6 addresses will be delivered to the NFS lock server.

As to why exactly the NFS developers has chosen to do so1 I do not know, but it is not exclusive to NFS: see for instance the OpenSSH daemon, which binds the IPv4 and IPv6 addresses separately (by default both the "any addresses", IPv4 0.0.0.0 and IPv6 ::).

Also, some operating systems do not even support the IPV6_V6ONLY option (e.g. they don't allow it to be set), and the only behavior you get on those systems is complete separation of the port numbers space between IPv4 and IPv6, hence applications there must bind the same port twice if they want to support both IPv4 and IPv6.

1. I haven't investigated fully but here are possibly the relevant pieces of code

| improve this answer | |
  • Thank you very much for the explanation. – Terence Yim Aug 21 '19 at 18:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.