Skip to contentSkip to conversation

bind() should not return -EADDRINUSE

DISCUSSION Phillip Susi 2 participants 9 messages Dec 11, 2014

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Attempting to establish a connection to a remote host using the same local port, but a different remote port as the previous connection ( that is still in TIME_WAIT ) results in bind() returning -EADDRINUSE.
By changing the remote port, you avoid the conflict with the other
connection that is in TIME_WAIT, but since the remote port is not known when bind() is called, it incorrectly returns -EADDRINUSE. This check should not be done in bind(), but deferred until the remote port is known in the call to connect(), or listen().

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.17 (MingW32)

iQEcBAEBAgAGBQJUie4vAAoJENRVrw2cjl5R8CgH/jgdrBXs1Yso7XsHtrsUgO75 P8bY3Mf8eOuAkLvwbHopyGr19UZJJ+5zCQWc6bus9BRa7jSQvPCRw8fSjg3u+NXs r9/qEqiDrYwAJqV5SwqDPGU8xGwq8v31bbT09spGIL9fABW3krBFtDHcZ/PzGA/p UGDgELdkU7QIMKvC7FAV5RzvMXpmAI+m7iQiF936QkGZPN0AOCTea0sB+IpeidTO /ChLd2iaEqAmS6UGh3jIQSNcTB3Ho3imHHMjTCel2v8+SgCBb2Tp3HzfmmIsGAnh YeH+ZCNHD08c+k9yprEVjCH6fwMOo7CWzyPnSme+Ggk0L5r9oj8iz4xIeIMv43o= =Ou3S
-----END PGP SIGNATURE-----

maintainer
#1 lore raw

From: Phillip Susi <[email protected]>
Date: Thu, 11 Dec 2014 14:19:11 -0500

Quoted 8 lines

Attempting to establish a connection to a remote host using the same local port, but a different remote port as the previous connection ( that is still in TIME_WAIT ) results in bind() returning -EADDRINUSE.
By changing the remote port, you avoid the conflict with the other
connection that is in TIME_WAIT, but since the remote port is not known when bind() is called, it incorrectly returns -EADDRINUSE. This check should not be done in bind(), but deferred until the remote port is known in the call to connect(), or listen().

Bind has to allocate and hold from everyone else on the system the local port at bind() time, so we cannot defer this decision.

#2 lore raw

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 13 lines · David Miller

From: Phillip Susi <[email protected]> Date: Thu, 11 Dec 2014 14:19:11 -0500

Quoted 9 lines

Attempting to establish a connection to a remote host using the same local port, but a different remote port as the previous connection ( that is still in TIME_WAIT ) results in bind() returning -EADDRINUSE. By changing the remote port, you avoid the conflict with the other connection that is in TIME_WAIT, but since the remote port is not known when bind() is called, it incorrectly returns -EADDRINUSE. This check should not be done in bind(), but deferred until the remote port is known in the call to connect(), or listen().

Quoted 2 lines

Bind has to allocate and hold from everyone else on the system the local port at bind() time, so we cannot defer this decision.

What on earth for? If two processes are going to connect to different remotes using the same source, that is perfectly fine. The only contention is if two processes want to listen() with the same local addr and wildcard remote.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.17 (MingW32)

iQEcBAEBAgAGBQJUifWYAAoJENRVrw2cjl5RpckH/2g9V0p3SFNvf1qmR1nxZjJ6 R19eosdoWvCL6B2pIqwvpy64ACqTf6MS3NrdZt6TwSz+8OKqBj/D8+IpKcAdo5kU Yzhl3qASkm17HTeOmGhw00pqJkD4FYzzwb8hw/OxwxWUwpVLvv+nMYHhF7vwgOy6 h90Kmj6ycOeY/+sX5Woe5RheKq+AlDqJGAELk1Vs9lrRDDa/3o/HqEQX5HNsohyC ib2dJRAdCuNN9KjSKuVLnCu4Tf1UB5W+efSK21qN/s1r0a0RWXMe2ph6JrYQsg2e H2nl7Ifiv/4VbuvRkabSsrge8bJtw76c2uMpxw1GHNUN1rNnxhGAj4J1oOIp4rQ= =LXdQ
-----END PGP SIGNATURE-----

maintainer
#3 lore raw

From: Phillip Susi <[email protected]>
Date: Thu, 11 Dec 2014 14:50:48 -0500

Quoted 17 lines

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 13 lines · David Miller

From: Phillip Susi <[email protected]> Date: Thu, 11 Dec 2014 14:19:11 -0500

Quoted 9 lines

Attempting to establish a connection to a remote host using the same local port, but a different remote port as the previous connection ( that is still in TIME_WAIT ) results in bind() returning -EADDRINUSE. By changing the remote port, you avoid the conflict with the other connection that is in TIME_WAIT, but since the remote port is not known when bind() is called, it incorrectly returns -EADDRINUSE. This check should not be done in bind(), but deferred until the remote port is known in the call to connect(), or listen().

Quoted 7 lines
Quoted 2 lines

Bind has to allocate and hold from everyone else on the system the local port at bind() time, so we cannot defer this decision.

What on earth for? If two processes are going to connect to different remotes using the same source, that is perfectly fine. The only contention is if two processes want to listen() with the same local addr and wildcard remote.

But you don't know ahead of time what the processes are going to do, that's the problem.

You cannot leave the port available and pretend to another process that he will be able to use it.

Port allocation failures must be signalled at bind() time.

#4 lore raw

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 8 lines · David Miller

But you don't know ahead of time what the processes are going to do, that's the problem.

You cannot leave the port available and pretend to another process that he will be able to use it.

Port allocation failures must be signalled at bind() time.

Says who? The man pages for both listen() and connect() say they can return EADDRINUSE.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.17 (MingW32)

iQEcBAEBAgAGBQJUifvIAAoJENRVrw2cjl5R+r8H/jb84r9KUgMQcfFAPB4aYQKt ou188Bpv6aa1AB1yt99il8bulvXMO5m0NuLG8NcYIDnt0zo1xaVrbxelNHIkx0XQ Gj67Ozc+yMOQ6izHUPMNgB9lI3q/GBhI6dt5/5NnIeAx4VzCQIhT1nKT6LRo4J6z k6R7vyXrm9M7X0A3hh7Dpapv/JWuzZfZYOZP+JQP/BSLorEX0+pZHoqOl0Cy+bwo rp/oaAAaQe+cX95dplXLVmXoh6JxjBTkXqWEEHTnNNbz3LsY+e7aokz3Pl9kQw3M hn1q9PSC+JMhxCI3AOgukIwlK3ps7y78PiQHxds/K/ZNVzaaeJAY+FryppUijPk= =/oDW
-----END PGP SIGNATURE-----

maintainer
#5 lore raw

From: Phillip Susi <[email protected]>
Date: Thu, 11 Dec 2014 15:17:12 -0500

Quoted 1 line

Says who?

Says multiple decades of precendence.

#6 lore raw

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 6 lines · David Miller

From: Phillip Susi <[email protected]> Date: Thu, 11 Dec 2014 15:17:12 -0500

Quoted 1 line

Says who?

Says multiple decades of precendence.

"It has always been broken, so it should stay broken" isn't a very compelling argument.

Would it cause programs to break if they get the error at listen() time instead of bind() time ( as the man page indicates it can )? I think not.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.17 (MingW32)

iQEcBAEBAgAGBQJUif1OAAoJENRVrw2cjl5RW8YH/0Rmg3JXGHJZr/z9H56F0Tfo m9mGM5THOUIXFaCugiqea/6Y9j1qvZC4OJdoB8Ve/bDTpTa2bs3SHd81eEntVpGI hXoeMw5RQxUuiBpKLmkWp+ma8Cl01qIADkTdRG2F/pPa8ee9xd4Lx0UGV6skUnVP 6HVuqeNxPS1xESQMpUAgO8KLGkvzB1/y8+7iBuc0fINZuox4KX8CVwzQB7d9I+G1 gf+yMaFtsDnNeGrXLKdSj7q+/yV61AgigSt3IeFIdUz+trbZa2W/6vUkBqVPB9bo QEClO9JROTIkkl2ErUyd+bnrKTNJR0/tkOUmqf8JjQhjSnozD/u0JdoQRMvjQtk= =PUUw
-----END PGP SIGNATURE-----

maintainer
#7 lore raw

From: Phillip Susi <[email protected]>
Date: Thu, 11 Dec 2014 15:23:45 -0500

Quoted 9 lines

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 5 lines · David Miller

From: Phillip Susi <[email protected]> Date: Thu, 11 Dec 2014 15:17:12 -0500

Quoted 1 line

Says who?

Quoted 8 lines
Quoted 1 line

Says multiple decades of precendence.

"It has always been broken, so it should stay broken" isn't a very compelling argument.

Would it cause programs to break if they get the error at listen() time instead of bind() time ( as the man page indicates it can )? I think not.

You will definitely break programs that look for a locally available port by iterating over bind() calls.

Sorry, this is not changing, no matter how strongly you may wish it to.

#8 lore raw

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 5 lines · David Miller

You will definitely break programs that look for a locally available port by iterating over bind() calls.

Sorry, this is not changing, no matter how strongly you may wish it to.

According to this very nice post, it is how BSD does it, at least when you specify SO_REUSEADDR:

http://stackoverflow.com/a/14388707/884259

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.17 (MingW32)

iQEcBAEBAgAGBQJUig3WAAoJENRVrw2cjl5ROzkIAJMyXGo6OA34TFz2pXlWUlLR +aA6UGC99oM6QV0y/sFnRGSlp4tIMTUQuFS7JzVCKHNRbm9dixtTdXLKpinBuUw/ Y1ZIO1+DyV457T05Q7w9oBxxxNqdLCRlLnVxolTiLN5IJ0mkEN+CaVJVuSl/Tx+S YtEmCyDShpE+xwQndOUQtt0WU2ZonrKGhYH1aA6YRSyxfX1N4vTuSKqCUvsSubfm r3tt22A6FaRey0pHzxSqzNcyvHe63THC8b556ggOcQM+yFf3C92FNyvyUWxETtdb 2VrXgGEYnXtcLXtSwYLOnQAXwW9yRg64BkinMDybVt7b6aNDG5653+Vi/NniysU= =NxIM
-----END PGP SIGNATURE-----