I was trying to debug port allocation problems in Jenkins on OS X by listening to certain ports with netcat, which led to some weird results.
In a terminal on OS X 10.8.2:
$ uname -rs
Darwin 12.2.1
$ nc -l 54321
Then in an second terminal:
$ nc -l 54321
And in a third terminal, lsof
shows that both instances have bound to the same port:
$ lsof -i | grep 54321
nc 70706 chris 3u IPv4 0x55618c024692f4d1 0t0 TCP *:54321 (LISTEN)
nc 70769 chris 3u IPv4 0x55618c0232cb8661 0t0 TCP *:54321 (LISTEN)
On Linux:
First terminal:
$ uname -rs
Linux 3.2.0-34-generic
$ nc -l 54321
Second terminal:
$ nc -l 54321
nc: Address already in use
Why doesn't OS X also report that the address is already in use?
The binary on OS X is setting the SO_REUSEPORT socket option, which allows completely duplicate bindings (setsockopt on OS X). You can verify this using dtrace on OS X.
The netcat binary on Linux does not do this, so you get a bind error as expected. Again, you can verify that using strace. I belive SO_REUSEPORT is deprecated, or not even available on newer Linux kernels.