12

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?

Christopher Orr
  • 110,418
  • 27
  • 198
  • 193
  • 1
    I don't know the `lsof -i` output syntaxis, but what are `0x55618c024692f4d1` and `0x55618c0232cb8661`? If it are IP addresses, then it's obviously because the listener was bound to a specific IP address and not the "any" address. – CodeCaster Dec 05 '12 at 15:49
  • They're meaningless memory addresses. The only purpose they have is to identify that these are two distinct sockets (e.g, not the result of a `fork()` or `dup()`). –  Dec 05 '12 at 16:28
  • Running `lsof -i` gives me 27 unique values for that field ("DEVICE"); I believe it's a memory address. The final column shows that the sockets are bound to `*`. – Christopher Orr Dec 05 '12 at 16:28
  • Of course, and they're too long to be IPv4 addresses anyway. I stand corrected. :-) – CodeCaster Dec 05 '12 at 16:49

1 Answers1

10

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.

ruffin
  • 16,507
  • 9
  • 88
  • 138
Neal
  • 6,722
  • 4
  • 38
  • 31
  • Thanks for the info! That also explains why if another piece of software was running, `nc` *did* complain that the port was already in use. – Christopher Orr Dec 06 '12 at 20:48
  • For info, the SO_REUSEPORT socket option was added to Linux 3.9: https://lwn.net/Articles/542629/ – Christopher Orr May 28 '15 at 08:49
  • This is helpful however can you provide an example of `dtrace` which can help a programmer confirm this? The examples I've found online are sparse and a bit hard to understand, especially if that programmer is unfamiliar with C. This makes it harder to identify for those dealing with this issue downstream such as in an interpreted / JIT fashion. – tresf May 12 '21 at 17:10